Storing and updating lists in Python dictionaries: why does this happen?

I have a list of data that looks like the following:

// timestep,x_position,y_position
0,4,7
0,2,7
0,9,5
0,6,7
1,2,5
1,4,7
1,9,0
1,6,8

... and I want to make this look like:

0, (4,7), (2,7), (9,5), (6,7)
1, (2,5), (4,7), (9,0), (6.8)

My plan was to use a dictionary, where the value of t is the key for the dictionary, and the value against the key would be a list. I could then append each (x,y) to the list. Something like:

# where t = 0, c = (4,7), d = {}

# code 1
d[t].append(c)

Now this causes IDLE to fail. However, if I do:

# code 2
d[t] = []
d[t].append(c)

... this works.

So the question is: why does code 2 work, but code 1 doesn't?

PS Any improvement on what I'm planning on doing would be of great interest!! I think I will have to check the dictionary on each loop through the input to see if the dictionary key already exists, I guess by using something like max(d.keys()): if it is there, append data, if not create the empty list as the dictionary value, and then append data on the next loop through.


Asked by: Alina542 | Posted: 05-10-2021






Answer 1

Let's look at

d[t].append(c)

What is the value of d[t]? Try it.

d = {}
t = 0
d[t]

What do you get? Oh. There's nothing in d that has a key of t.

Now try this.

d[t] = []
d[t]

Ahh. Now there's something in d with a key of t.

There are several things you can do.

  1. Use example 2.
  2. Use setdefault. d.setdefault(t,[]).append(c).
  3. Use collections.defaultdict. You'd use a defaultdict(list) instead of a simple dictionary, {}.

Edit 1. Optimization

Given input lines from a file in the above form: ts, x, y, the grouping process is needless. There's no reason to go from a simple list of ( ts, x, y ) to a more complex list of ( ts, (x,y), (x,y), (x,y), ... ). The original list can be processed exactly as it arrived.

d= collections.defaultdict(list)
for ts, x, y in someFileOrListOrQueryOrWhatever:
    d[ts].append( (x,y) )

Edit 2. Answer Question

"when initialising a dictionary, you need to tell the dictionary what the key-value data structure will look like?"

I'm not sure what the question means. Since, all dictionaries are key-value structures, the question's not very clear. So, I'll review the three alternatives, which may answer the question.

Example 2.

Initialization

d= {}

Use

if t not in d:
    d[t] = list()
d[t].append( c )

Each dictionary value must be initialized to some useful structure. In this case, we check to see if the key is present; when the key is missing, we create the key and assign an empty list.

Setdefault

Initialization

d= {}

Use

d.setdefault(t,list()).append( c )

In this case, we exploit the setdefault method to either fetch a value associated with a key or create a new value associated with a missing key.

default dict

Initialization

import collections
d = collections.defaultdict(list)

Use

d[t].append( c )

The defaultdict uses an initializer function for missing keys. In this case, we provide the list function so that a new, empty list is created for a missing key.

Answered by: Kirsten115 | Posted: 06-11-2021



Answer 2

I think you want to use setdefault. It's a bit weird to use but does exactly what you need.

d.setdefault(t, []).append(c)

The .setdefault method will return the element (in our case, a list) that's bound to the dict's key t if that key exists. If it doesn't, it will bind an empty list to the key t and return it. So either way, a list will be there that the .append method can then append the tuple c to.

Answered by: Emma366 | Posted: 06-11-2021



Answer 3

dict=[]  //it's not a dict, it's a list, the dictionary is dict={}
elem=[1,2,3]
dict.append(elem)

you can access the single element in this way:

print dict[0] // 0 is the index

the output will be:

[1, 2, 3]

Answered by: Walter392 | Posted: 06-11-2021



Answer 4

In the case your data is not already sorted by desired criteria, here's the code that might help to group the data:

#!/usr/bin/env python
"""
$ cat data_shuffled.txt
0,2,7
1,4,7
0,4,7
1,9,0
1,2,5
0,6,7
1,6,8
0,9,5
"""
from itertools   import groupby
from operator    import itemgetter

# load the data and make sure it is sorted by the first column
sortby_key = itemgetter(0)
data = sorted((map(int, line.split(',')) for line in open('data_shuffled.txt')),
              key=sortby_key)

# group by the first column
grouped_data = []
for key, group in groupby(data, key=sortby_key):
    assert key == len(grouped_data) # assume the first column is 0,1, ...
    grouped_data.append([trio[1:] for trio in group])

# print the data
for i, pairs in enumerate(grouped_data):
    print i, pairs

Output:

0 [[2, 7], [4, 7], [6, 7], [9, 5]]
1 [[4, 7], [9, 0], [2, 5], [6, 8]]

Answered by: Edward556 | Posted: 06-11-2021



Similar questions

dictionary - Python Dictionaries: Grouping Key, Value pairs based on a common key, value

I have a list that contains dictionaries like this: list1 = [{'name': 'bob', 'email': 'bob@bob.com', 'address': '123 house lane', 'student_id': 12345}, {'name': 'steve', 'email': 'steve@steve.com', 'address': '456 house lane', 'student_id': 34567}, {'name': 'bob', 'email': 'bob2@bob2.com', 'address': '789 house lane', 'student_id': 45678}] Is there a way in python to group selected key, v...


dictionary - Python Dictionaries: Different way to iterate through a dict

I am searching for a different way to access every key in a dictionary within a for loop. Underneath, there is an example code, where I iterate through a dictionary and access every key with the help of a counter and a if statement. Is there another way to access the keys, without a counter or an if statement? def string_to_dict(csv): dict = [] tmp = csv.splitlines() for i in tmp: tm...


sorting - Python dictionaries: changing the order of nesting

I have a dictionary, with 300 key value pairs, where each of the keys are integers and the values are dictionaries with three key value pairs. The inner dictionaries all have the same keys, but different values. The whole thing looks pretty much like this: nested_dicts = {1: {'name1':88.4, 'name2':22.1, 'name3':115.7}, 2: {'name1':89.4, 'name2':23.7, 'name3':117.9} ... 300:{'name1':110...


python - List of dictionaries: get() schould loop over list

I know it is easy to implement. I want a dictionary like class, which takes a list of dictionaries in the constructor. If you read from this dict by key, the dict-class should check the list of dictionaries and return the first value. If none contains this key KeyError should be thrown like a normal dict. This dictionary container should be read only for my usage.


Python dictionaries: merging multiple value lists into a single list of unique values

I am just learning Python using Python 2.7. I have a csv file with two columns. The columns are: Coll_id: the entries may be single collectors or may be groups Participant_Coll_id: if the Coll_id is a single collector then the value will be null. If the Coll_id is a group then there will be a single row for each Participant in the group. A sample is here: Coll_id,Participant_Coll_id&...


python - Multi-line dictionaries: Replace the key as per a word in value

I have a dictionary in which I have to replace all the keys depending on a word in the value set. So my dictionary is: { 23: {'score': -8.639, 'char': False, 'word': 'positive'} } { 56: {'score': -5.6, 'char': False, 'word': 'neutral'} } { 89: {'score': -8.9, 'char': False, 'word': 'positive'} } { 34: {'score': -2.3, 'char': Tru, 'word': 'negative'} } If the values part of dic...


python - Dictionaries: checking values for selected keys

Below you can find simple script for calculation of the protein mass in given sequence import re def make_table(yy): letter=r"^[A-Z]" mass= r"[0-9]{1,2}" #list of aa table=open(yy,'r') aa=[i for line in table for i in line if re.match(letter,i)] table.close() table=open(yy,'r').readlines() xz=''.join([line[:-1] for line in table]) mass= re.findall(r"[-+]?\d*\.\d+|\d+"...


python - Having trouble with functions calling other functions through dictionaries: could someone please explain this code to me?

This is used in a text-based game to determine if a different room has been entered in order to run a function. It is learning exercise so I am sure the code is not optimal. The whole thing is started by running the code on the last line. def runner(map, start): next = start while True: room = map[next] print "\n--------" next = room() runner(ROOMS, 'central_corridor')


python - Dictionaries: How to get duplicate input by the user and count how many times it was entered?

names = [] print("Duplicate names won't be in the list!") # reminder while True: userInput = input("Enter a name: ") if userInput == "": # condition to terminate loop print("You've entered these names, duplicated names won't be included") print(names) break elif userInput not in names: # condition to see if input is duplicated names.append(userInput) # if satisfied, add...


python - Dictionaries: added value to one key also gets added to other keys

I have a big excel file with 36352 rows, containing information on burglaries. Each row contains a date and the name of the municipality where the event occurred. I'm trying to convert this dataset into a calendar map for each municipality, stating how many burglaries there were on every day of the year. I first created a calendar map (dictionary), where the date is the key and the value is the number of burglaries...


Python Dictionaries: Copying, stripping, & calculating a dictionary

This question already has answers here:


dictionary - Python Dictionaries: Grouping Key, Value pairs based on a common key, value

I have a list that contains dictionaries like this: list1 = [{'name': 'bob', 'email': 'bob@bob.com', 'address': '123 house lane', 'student_id': 12345}, {'name': 'steve', 'email': 'steve@steve.com', 'address': '456 house lane', 'student_id': 34567}, {'name': 'bob', 'email': 'bob2@bob2.com', 'address': '789 house lane', 'student_id': 45678}] Is there a way in python to group selected key, v...






Still can't find your answer? Check out these communities...



PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python



top