Converting Dictionary to List? [duplicate] - python

This question already has answers here:
How can I convert a dictionary into a list of tuples?
(13 answers)
Closed 3 years ago.
I'm trying to convert a Python dictionary into a Python list, in order to perform some calculations.
#My dictionary
dict = {}
dict['Capital']="London"
dict['Food']="Fish&Chips"
dict['2012']="Olympics"
#lists
temp = []
dictList = []
#My attempt:
for key, value in dict.iteritems():
aKey = key
aValue = value
temp.append(aKey)
temp.append(aValue)
dictList.append(temp)
aKey = ""
aValue = ""
That's my attempt at it... but I can't work out what's wrong?

dict.items()
Does the trick.

Converting from dict to list is made easy in Python. Three examples:
>> d = {'a': 'Arthur', 'b': 'Belling'}
>> d.items()
[('a', 'Arthur'), ('b', 'Belling')]
>> d.keys()
['a', 'b']
>> d.values()
['Arthur', 'Belling']

Your problem is that you have key and value in quotes making them strings, i.e. you're setting aKey to contain the string "key" and not the value of the variable key. Also, you're not clearing out the temp list, so you're adding to it each time, instead of just having two items in it.
To fix your code, try something like:
for key, value in dict.iteritems():
temp = [key,value]
dictlist.append(temp)
You don't need to copy the loop variables key and value into another variable before using them so I dropped them out. Similarly, you don't need to use append to build up a list, you can just specify it between square brackets as shown above. And we could have done dictlist.append([key,value]) if we wanted to be as brief as possible.
Or just use dict.items() as has been suggested.

You should use dict.items().
Here is a one liner solution for your problem:
[(k,v) for k,v in dict.items()]
and result:
[('Food', 'Fish&Chips'), ('2012', 'Olympics'), ('Capital', 'London')]
or you can do
l=[]
[l.extend([k,v]) for k,v in dict.items()]
for:
['Food', 'Fish&Chips', '2012', 'Olympics', 'Capital', 'London']

>>> a = {'foo': 'bar', 'baz': 'quux', 'hello': 'world'}
>>> list(reduce(lambda x, y: x + y, a.items()))
['foo', 'bar', 'baz', 'quux', 'hello', 'world']
To explain: a.items() returns a list of tuples. Adding two tuples together makes one tuple containing all elements. Thus the reduction creates one tuple containing all keys and values and then the list(...) makes a list from that.

Probably you just want this:
dictList = dict.items()
Your approach has two problems. For one you use key and value in quotes, which are strings with the letters "key" and "value", not related to the variables of that names. Also you keep adding elements to the "temporary" list and never get rid of old elements that are already in it from previous iterations. Make sure you have a new and empty temp list in each iteration and use the key and value variables:
for key, value in dict.iteritems():
temp = []
aKey = key
aValue = value
temp.append(aKey)
temp.append(aValue)
dictList.append(temp)
Also note that this could be written shorter without the temporary variables (and in Python 3 with items() instead of iteritems()):
for key, value in dict.items():
dictList.append([key, value])

If you're making a dictionary only to make a list of tuples, as creating dicts like you are may be a pain, you might look into using zip()
Its especialy useful if you've got one heading, and multiple rows. For instance if I assume that you want Olympics stats for countries:
headers = ['Capital', 'Food', 'Year']
countries = [
['London', 'Fish & Chips', '2012'],
['Beijing', 'Noodles', '2008'],
]
for olympics in countries:
print zip(headers, olympics)
gives
[('Capital', 'London'), ('Food', 'Fish & Chips'), ('Year', '2012')]
[('Capital', 'Beijing'), ('Food', 'Noodles'), ('Year', '2008')]
Don't know if thats the end goal, and my be off topic, but it could be something to keep in mind.

Related

Replace elements in a nested dict with the appropriate in a list

I have such following a dict and a list.
mylist= ['1H1.PyModule.md',
'1H2.Class.md',
'1H3.MetaObject.md',
'2B1D0.Data.md',
'2B1D1.Primitive.md',
'2B1D2.Operator.md',
'2B2D3.Container.md',
'2B2S0.Function.md',
'2B2S0.Statemment.md',
'2B2S1.Controlled_Loop.md',
'2B2S2.Conditions.md',
'2B2S3.Except.md',
...
]
mydict = {'Body': {'Data': ['1.primitive', '2.operator', '3.container'],
'Statement': ['0.function', '1.controlled_loop', '2.condition', '3.except']},
'Header': ['1.Modle', '2.Class', '3.Object'],
...}
I attempt to repalce the strings in mydict with the appropriate in mylist
I can figure out '2B1D0.Data.md' has the shortest length,
So I slice the keyward 'Data'
In [82]: '2B1D0.Data.md'[-7:-3]
Out[82]: 'Data'
The dict has both a nested list and nested dict.
So I write a iteration function with type checking
if an item's value isinstance(value,list), renew that value,
if an item's value isinstance(value, dict),call the function replace_ele()to continue.
I name string in mylist as str_of_list,
while string in mydict as str_of_dict for readable concerns.
#replace one string in mydict
def replace_ele(mydict, str_of_list):
for key, value in mydict.items():
if isinstance(value, list): #type checking
for str_of_dict in value:
#replace str_of_dict with str_of_list
if str_of_list[-7:-3].lower() == str_of_dict[-4:]: #[-7:-3] the shortest length
value.remove(str_of_dict)
value.append(str_of_list)
value.sort()
mydict[key] = value
#iteration if a dict
if isinstance(value, dict):
replace_ele(value,str_of_list)
for str_of_list in mylist:
replace_ele(mydict, str_of_list)
Then running and outputs:
Out[117]:
{'Body': {'Data': ['2B1D1.Primitive.md',
'2B1D2.Operator.md',
'2B2D3.Container.md'],
'Statement': ['2B2S0.Function.md',
'2B2S0.Function.md',
'2B2S1.Controlled_Loop.md',
'2B2S3.Except.md']},
'Header': ['1.Modle', '1H2.Class.md', '1H3.MetaObject.md']
....}
I assume that such a problem can be solved with less codes.
However, I cannot find that solution with the limited knowledge.
How to accomplish it elegantly?
My suggestion is that you create a function to reduce element of mylist and elements in lists of mydict values to the same format:
For example, you can split by '.' character, take the second field, convert it to lower case:
def f(s):
return s.split('.')[1].lower()
E.g.:
>>> f('2B2S1.Controlled_Loop.md')
'controlled_loop'
>>> f('1.controlled_loop')
'controlled_loop'
Now, from mylist create a dict to hold replacements:
mylist_repl={f(x): x for x in mylist}
i.e. mylist_repl contains key: value items such as 'metaobject': '1H3.MetaObject.md'.
With dict mylist_repl and function f, it is easy to transform a list from mydict to the desired value, example:
>>> [mylist_repl[f(x)] for x in ['1.primitive', '2.operator', '3.container']]
['2B1D1.Primitive.md', '2B1D2.Operator.md', '2B2D3.Container.md']
Also note that this dictionary lookup is more efficient (i.e.: faster) than a nested for loop!
If you have different replacement logic, you probably only need to change how f maps items from two different sets to a common key.

Update values for multiple keys in python

What is the cleanest way to update the values of multiple keys in a dictionary to the values stored in a tuple?
Example:
I want to go from
>>>mydict = {'a':None, 'b':None, 'c':None, 'd':None}
>>>mytuple = ('alpha', 'beta', 'delta')
to
>>>print mydict
{'a':'alpha', 'b':'beta', 'c':None, 'd':'delta'}
Is there an easy one-liner for this? Something like this seems to be getting close to what I want.
EDIT:
I don't wish to assign values to keys based on their first letter. I'm just hoping for something like
mydict('a','b','d') = mytuple
Obviously that doesn't work, but I'm hoping for something similar to that.
If you're trying to create a new dictionary:
d = dict(zip(keys, valuetuple))
If you're trying to add to an existing one, just change the = to .update(…).
So, your example can be written as:
mydict.update(dict(zip('abd', mytuple))))
If you're doing this more than once, I'd wrap it up in a function, so you can write:
setitems(d, ('a', 'b', 'd'), mytuple)
Or maybe a "curried" function that parallels operator.itemgetter?
You could use list comprehension to make it a one-liner, though it's not super efficient.
keys = [ 'a', 'b', 'c', 'd']
values = ['alpha', 'beta', 'delta']
dictionary = dict([(k,v) for k in keys for v in values if v.startswith(k)])
print dictionary #prints {'a': 'alpha', 'b': 'beta', 'd': 'delta'}
Assuming the association key <-> value is the first letter of the value is the first letter of the key.
dict( (v[0],v) for v in mytuple if v[0] in mydict)
I would avoid one-liners in this case. It makes code more readable.
for t in mytuple:
if t[0] in mydict.keys():
mydict[t[0]] = t
If you want to add mytuple items even if the key does not exist, simply remove the if statement.

How to iterate through dict values containing lists and remove items?

Python novice here. I have a dictionary of lists, like so:
d = {
1: ['foo', 'foo(1)', 'bar', 'bar(1)'],
2: ['foobaz', 'foobaz(1)', 'apple', 'apple(1)'],
3: ['oz', 'oz(1)', 'boo', 'boo(1)']
}
I am trying to figure out how to loop through the keys of the dictionary and the corresponding list values and remove all strings in each in list with a parantheses tail. So far this is what I have:
for key in keys:
for word in d[key]...: # what else needs to go here?
regex = re.compile('\w+\([0-9]\)')
re.sub(regex, '', word) # Should this be a ".pop()" from list instead?
I would like to do this with a list comprehension, but as I said, I can't find much information on looping through dict keys and corresponding dict value of lists. What's the most efficient way of setting this up?
You can re-build the dictionary, letting only elements without parenthesis through:
d = {k:[elem for elem in v if not elem.endswith(')')] for k,v in d.iteritems()}
temp_dict = d
for key, value is temp_dict:
for elem in value:
if temp_dict[key][elem].find(")")!=-1:
d[key].remove[elem]
you can't edit a list while iterating over it, so you create a copy of your list as temp_list and if you find parenthesis tail in it, you delete corresponding element from your original list.
Alternatively, you can do it without rebuilding the dictionary, which may be preferable if it's huge...
for k, v in d.iteritems():
d[k] = filter(lambda x: not x.endswith(')'), v)

Python List Comprehesion conversion

So I have a script like this
for key, Value in mydictionary.iteritems():
if 'Mammal' in Value[1]:
#because the value is a list of 2 items and I want to get at the second one
Value[1] = Value[1].strip('Mammal')
This code effectively removes Mammal from the beginning of the second item in the Value list. Now I want to make this nicer python looking with list comprehension so I came up with this but obviously is wrong.... Any help?
Value[1] = [Value[1].strip('Mammal') for Key, Value in mydictionary.iteritems() if 'Mammal' in Value[1] ]
Also, on the same lines, a list comprehension to list all the keys in this dictionary. I am having a hard time coming up with that one.
I came up with:
for key, Value in mydictionary.iteritems():
Templist.append(key)
but as a list comprehension I am thinking....but it doesn't work :(
alist = [key for Key, Value in mydictionary.iteritems()]
mydictionary = {
1: [4, "ABC Mammal"],
2: [8, "Mammal 123"],
3: [15, "Bird (Not a Mammal)"]
}
mydictionary = {key: ([value[0], value[1].strip('Mammal')] if 'Mammal' in value[1] else value) for key, value in mydictionary.iteritems()}
print mydictionary
Output:
{1: [4, 'ABC '], 2: [8, ' 123'], 3: [15, 'Bird (Not a Mammal)']}
Although I wouldn't call this objectively "nicer looking", so the iterative method may be preferable.
List comprehension creates a new list
If you were able to use strip(), then Value[1] is a string - not a list
You may do 2nd part just with dictionary method keys() - both your attempts are redundant.
alist = mydictionary.keys()
mydict = {'a':['Mammal','BC','CD'],
'b':['AB','XY','YZ'],
'c':['Mammal','GG','FD'],}
print [x for x,y in mydict.items() if y[0]=='Mammal']
You should not use a list comprehension solely to create side effects. You can, but it is considered bad practice, and you should stick with the for loop.
Anyway, since you are working with a dictionary, you may be looking for a dict comprehension:
mydictionary = {'foo': ['unknown', 'Mammal is great'],
'bar': ['something', 'dont touch me']}
mydictionary = {k: [a, b.replace('Mammal', '', 1)] for k, [a, b] in mydictionary.iteritems() if b.startswith('Mammal')}
Also note that using if you use dict comprehension, you create a new dictionary instead of replacing the values in your old one.
...
Value[1] = Value[1].strip('Mammal')
...
This code effectively removes Mammal from the beginning of the second item in the Value list.
No, it does not. It replaces all occurrences of M, a, m and l from the beginning and the end of that item. Better use the replace method to replace the first occurrence of Mammal with an empty string.
alist = [key for Key, Value in mydictionary.iteritems()]
You have a typo here. It should read:
alist = [key for key, value in mydictionary.iteritems()]
or just
alist = mydictionary.keys()

How to implement associative array (not dictionary) in Python?

I trying to print out a dictionary in Python:
Dictionary = {"Forename":"Paul","Surname":"Dinh"}
for Key,Value in Dictionary.iteritems():
print Key,"=",Value
Although the item "Forename" is listed first, but dictionaries in Python seem to be sorted by values, so the result is like this:
Surname = Dinh
Forename = Paul
How to print out these with the same order in code or the order when items are appended in (not sorted by values nor by keys)?
You can use a list of tuples (or list of lists). Like this:
Arr= [("Forename","Paul"),("Surname","Dinh")]
for Key,Value in Arr:
print Key,"=",Value
Forename = Paul
Surname = Dinh
you can make a dictionary out of this with:
Dictionary=dict(Arr)
And the correctly sorted keys like this:
keys = [k for k,v in Arr]
Then do this:
for k in keys: print k,Dictionary[k]
but I agree with the comments on your question: Would it not be easy to sort the keys in the required order when looping instead?
EDIT: (thank you Rik Poggi), OrderedDict does this for you:
od=collections.OrderedDict(Arr)
for k in od: print k,od[k]
First of all dictionaries are not sorted at all nor by key, nor by value.
And basing on your description. You actualy need collections.OrderedDict module
from collections import OrderedDict
my_dict = OrderedDict([("Forename", "Paul"), ("Surname", "Dinh")])
for key, value in my_dict.iteritems():
print '%s = %s' % (key, value)
Note that you need to instantiate OrderedDict from list of tuples not from another dict as dict instance will shuffle the order of items before OrderedDict will be instantiated.
You can use collections.OrderedDict. It's available in python2.7 and python3.2+.
This may meet your need better:
Dictionary = {"Forename":"Paul","Surname":"Dinh"}
KeyList = ["Forename", "Surname"]
for Key in KeyList:
print Key,"=",Dictionary[Key]
'but dictionaries in Python are sorted by values' maybe I'm mistaken here but what game you that ideea? Dictionaries are not sorted by anything.
You would have two solutions, either keep a list of keys additional to the dictionary, or use a different data structure like an array or arrays.
I wonder if it is an ordered dict that you want:
>>> k = "one two three four five".strip().split()
>>> v = "a b c d e".strip().split()
>>> k
['one', 'two', 'three', 'four', 'five']
>>> v
['a', 'b', 'c', 'd', 'e']
>>> dx = dict(zip(k, v))
>>> dx
{'four': 'd', 'three': 'c', 'five': 'e', 'two': 'b', 'one': 'a'}
>>> for itm in dx:
print(itm)
four
three
five
two
one
>>> # instantiate this data structure from OrderedDict class in the Collections module
>>> from Collections import OrderedDict
>>> dx = OrderedDict(zip(k, v))
>>> for itm in dx:
print(itm)
one
two
three
four
five
A dictionary created using the OrderdDict preserves the original insertion order.
Put another way, such a dictionary iterates over the key/value pairs according to the order in which they were inserted.
So for instance, when you delete a key and then add the same key again, the iteration order is changes:
>>> del dx['two']
>>> for itm in dx:
print(itm)
one
three
four
five
>>> dx['two'] = 'b'
>>> for itm in dx:
print(itm)
one
three
four
five
two
As of Python 3.7, regular dicts are guaranteed to be ordered, so you can just do
Dictionary = {"Forename":"Paul","Surname":"Dinh"}
for Key,Value in Dictionary.items():
print(Key,"=",Value)

Categories