Adding a item into a a dictionary in Python - python

I have a dictionary that store the values as lists for each key. For example:
dict1={}
dict1["A"]=[]
I want to append numbers into this list now, but how do I do this correctly? I tried dict1["A"]=dict1["A"].append(1)
this only appended "None". How do I do this?

You just need to call append()
dict1["A"].append(1)
Since the return value of append() itself is None, your version just replaced the old value (a list) with None after you successfully added the item to the list.
A quick demo:
>>> dict1 = {'A': []}
>>> dict1['A'].append(1)
>>> dict1
{'A': [1]}
In Python, in-place operations such as appending to the list, return None:
>>> alist = []
>>> alist.append(1) is None
True
>>> alist
[1]
but as you can see, the list itself was changed.

No need to reassign. Just do dict1["A"].append(1).
The mistake you have done is dict1["A"].append(1) returns None and that you were assigning it back to dict1. Which explains the None you were getting...

That's because append() changes the list in-place and returns None. In your code you assigned that returned Value to dict1["A"]
In [25]: dict1={}
In [26]: dict1["A"]=[]
In [27]: dict1["A"].append(1) #try print dict1["A"].append(1) here
In [28]: dict1
Out[28]: {'A': [1]}

Related

Is there a reason for unpacking a list then putting it back into a list?

I'm trying to understand the following Python line:
result = {'key_A': [*dict_A.keys()], 'key_B': "dummy_string"}
Result is dictionary that holds a list in Result['key_A'] and string in Result['key_b']. But I'm not sure why the dict_A.keys() has to be unpacked, only to be put into a list again. Is there a reason for this extra unpacking operation?
In Python 3 .keys does not return a list, but a dict_keys object, so if list is required it must be converted.
[*dict_A.keys()] is equivalent to list(dict_A.keys())
The dict.keys() function returns a view object, which represents the changes done to the dictionary.
simply put, changing the dictionary affects the key's object.
example:
a = {'a':1, 'b':2}
b = a.keys()
print(b)
a['c'] = 3
print(b)
Out:
dict_keys(['a', 'b'])
dict_keys(['a', 'b', 'c'])
Therefore, for maintaining the current state of the dictionary keys, convert to list.
The unpacking operator can be used to unpack generators/objects, so instead of having to do [key for key in dict_A.keys()], a user can use [*dict_A.keys()], as it will get each item of the generator and pack it back into a list. This is also similar to using list(dict_A.keys()).

Purging empty dictionaries from list of dictionary

I have a list of dictionaries like so:
[{'a':'21'},{},{'b':20'},{'c':'89'},{}]
What's the most efficient way to purge empty dictionaries from this list, end result being:
[{'a':'21'},{'b':'20'},{'c':'89'}]
I'm trying:
new_list_of_dictionaries = []
for dictionary in list_of_dictionaries:
if dictionary:
new_list_of_dictionaries.append(dictionary)
return new_list_of_dictionaries
I don't suppose this can be done in O(1) or something?
Just use a list comprehension, and filter on the boolean truth. An empty dictionary is considered false:
return [d for d in list_of_dictionaries if d]
In Python 2, you could also use the filter() function, using None as the filter:
return filter(None, list_of_dictionaries)
In Python 3 that returns an iterator, not a list, so you'd have to call list() on that (so return list(filter(None, ...))), at which point the list comprehension is simply more readable. Of course, if you don't actually need to have random access to the result (so direct index access to result[whatever]), then an iterator might still be a good idea anyway.
Note that this has to take O(N) time, you have to test each and every dictionary. Even if lists had some kind of automaticly updated map that lets you get the indices of the dictionaries that are empty in O(1) time, removing items from a list requires moving later entries forward.
Comprehension or filter (Python2, Python3):
return filter(None, list_of_dictionaries)
# Python3, if you prefer a list over an iterator
return list(filter(None, list_of_dictionaries))
None as filter function will filter out all non-truthy elements, which in the case of empty collections makes it quite concise.
could use a list comprehension?
myList = [{'a':'21'},{},{'b':'20'},{'c':'89'},{}]
result = [x for x in myList if x]
I did it in this way
d = [{'a': '21'}, {}, {'b': 20}, {'c': '89'}, {}]
new_d = []
for item in d:
check = bool(item)
if not check:
del item
else:
new_d.append(item)
print(new_d)
[{'a': '21'}, {'b': 20}, {'c': '89'}]

Comparing list with dictionary to make new list in python

I have one list and one dictionary. I want to compare the list values with the keys of the dictionary. If I have:
mydict = {'Hello':1,'Hi':2,'Hey':3}
and:
mylist = ['Hey','What\'s up','Hello']
I want the output to be:
output = [3, None, 1]
Thanks!
I tried [mydict[i] for i in mylist] and I get an error instead of None. I then tried using nested for loops (I deleted that bit) but I decided that was to inefficient.
Use a list comprehension:
output = [ mydict.get(key) for key in mylist ]
Note that dict.get returns None if the key is not in the dict.
Use dict.get(), which defaults to None if key does not exist:
[mydict.get(k) for k in mylist]
>>> mydict = {'Hello':1,'Hi':2,'Hey':3}
>>> mylist = ['Hey','What\'s up','Hello']
>>> out = [mydict.get(k) for k in mylist]
>>> out
[3, None, 1]

evaluation of list comprehensions in python

In trying to use a list comprehension to make a list given a conditional, I see the following:
In [1]: mydicts = [{'foo':'val1'},{'foo':''}]
In [2]: mylist = [d for d in mydicts if d['foo']]
In [3]: mylist
Out[3]: [{'foo': 'val1'}]
In [4]: mydicts[1]['foo'] = 'val2'
In [5]: mydicts
Out[5]: [{'foo': 'val1'}, {'foo': 'val2'}]
In [6]: mylist
Out[6]: [{'foo': 'val1'}]
I've been reading the docs to try and understand this but have come up with nothing so far, so I'll ask my question here: why is it that mylist never includes {'foo': 'val2'} even though the reference in the list comprehension points to mydict, which by In [6] contains {'foo': 'val2'}? Is this because Python eagerly evaluates list comprehensions? Or is the lazy/eager dichotomy totally irrelevant to this?
There's no lazy evaluation of lists in Python. List comprehensions simply create a new list. If you want "lazy" evaluation, use a generator expression instead.
my_generator_expression = (d for d in mydicts if d['foo']) # note parentheses
mydicts[1]['foo'] = 'val2'
print(my_generator_expression) # >>> <generator object <genexpr> at 0x00000000>
for d in my_generator_expression:
print(d) # >>> {'foo': 'val1'}
# >>> {'foo': 'val2'}
Note that generators differ from lists in several important ways. Perhaps the most notable is that once you iterate over them, they are exhausted, so they're best to use if you only need the data they contain once.
I think you're a bit confused about what list comprehensions do.
When you do this:
[d for d in mydicts if d['foo']]
That evaluates to a new list. So, when you do this:
mylist = [d for d in mydicts if d['foo']]
You're assigning that list as the value of mylist. You can see this very easily:
assert type(mylist) == list
You're not assigning "a list comprehension" that gets reevaluated every time to mylist. There are no magic values in Python that get reevaluated every time. (You can fake them by, e.g., creating a class with a #property, but that's not really an exception; it's the expression myobj.myprop that's being reevaluated, not myprop itself.)
In fact, mylist = [d for d in mydicts if d['foo']] is basically the same mylist = [1, 2, 3].* In both cases, you're creating a new list, and assigning it to mylist. You wouldn't expect the second one to re-evaluate [1, 2, 3] each time (otherwise, doing mylist[0] = 0 wouldn't do much good, because as soon as you try to view mylist you'd be getting a new, pristine list!). The same is true here.
* In Python 3.x, they aren't just basically the same; they're both just different types of list displays. In 2.x, it's a bit more murky, and they just happen to both evaluate to new list objects.
mylist contains the result of a previous list comprehension evaluation, it won't magically updated just because you update a variable that was used for its computation.

a=list().append("hello") vs a=list(); a.append("hello") in python?

I have
try:
a = list().append('hello')
but a is NoneType
try:
b = list()
b.append('hello')
and b is a list type
I think list() returns a list object, and list().append('hello') will use the return list to do append, but why is the value of a None?
list() does indeed return an empty list ([]), but the append method operates on a list in-place - it changes the list itself, and doesn't return a new list. It returns None instead.
For example:
>>> lst = []
>>> lst.append('hello') # appends 'hello' to the list
>>> lst
['hello']
>>> result = lst.append('world') # append method returns None
>>> result # nothing is displayed
>>> print result
None
>>> lst # the list contains 'world' as well now
['hello', 'world']
a = list().append('hello')
The above line, would create a new list, then invoke the append() method, and just store the return code of append() to the variable a. And since the value is None, it just means that the append() method does not have a return value.
To confirm this, you could try this:
>>> a = list()
>>> result = a.append('hello')
>>> print a
['hello']
>>> print result
None
You already got the answer to your question, but I'd just point out that the best way to do what you're trying to do is neither. It should be:
a = [ 'hello' ]

Categories

Resources