I have a list derived from a text file (filename) with an header
mylist = [l.split() for l in open(filename, "r")]
mylist = [['A','B','C','D'],['1','2','3','4'],['10','20','30','40'],['100','200','300','400']]
i wish to create a dictionary directly reading the file in order to save lines of code as:
mtlist_dist = {A: ['1','10','100'], B: [''2,'20','200'], C: ['3','30','300'], D: ['4','40','400']}
You can do this easily with zip and a dictionary comprehension:
>>> mylist = [['A','B','C','D'],['1','2','3','4'],['10','20','30','40'],['100','200','300','400']]
>>> {x[0]:x[1:] for x in zip(*mylist)}
{'A': ('1', '10', '100'), 'C': ('3', '30', '300'), 'B': ('2', '20', '200'), 'D': ('4', '40', '400')}
>>> {x[0]:list(x[1:]) for x in zip(*mylist)}
{'A': ['1', '10', '100'], 'C': ['3', '30', '300'], 'B': ['2', '20', '200'], 'D': ['4', '40', '400']}
>>>
In Python 3.x, the solution becomes even more concise with extended iterable unpacking:
>>> mylist = [['A','B','C','D'],['1','2','3','4'],['10','20','30','40'],['100','200','300','400']]
>>> {x:y for x,*y in zip(*mylist)}
{'D': ['4', '40', '400'], 'A': ['1', '10', '100'], 'C': ['3', '30', '300'], 'B': ['2', '20', '200']}
>>>
You can do it as:
my_dict = dict(zip(mylist[0], zip(*mylist[1:])))
>>> print my_dict
{'A': ('1', '10', '100'), 'C': ('3', '30', '300'), 'B': ('2', '20', '200'), 'D': ('4', '40', '400')
Related
This question already has answers here:
List of dicts to/from dict of lists
(14 answers)
Closed 4 years ago.
so given a list of dictionaries:
my_dict= [{'a': '4', 'b': '5', 'c': '1', 'd': '3'},
{'a': '1', 'b': '8', 'c': '1', 'd': '2'},
{'a': '7', 'b': '4', 'c': '1', 'd': '5'}]
and a list of keys in the dictionary for example [ 'a', 'b']
I am trying to make a list of dictionaries for both 'a' and 'b' for their respective values i.e the final product will resemble
new_dict = ['a':['4', '1', '7'], 'b':['5', '8', '4']]
any help will be appreciated
Using collections
Demo:
import collections
d = collections.defaultdict(list)
my_dict= [{'a': '4', 'b': '5', 'c': '1', 'd': '3'}, {'a': '1', 'b': '8', 'c': '1', 'd': '2'}, {'a': '7', 'b': '4', 'c': '1', 'd': '5'}]
for i in my_dict:
for k,v in i.items():
d[k].append(v)
print( d )
Output:
defaultdict(<type 'list'>, {'a': ['4', '1', '7'], 'c': ['1', '1', '1'], 'b': ['5', '8', '4'], 'd': ['3', '2', '5']})
I am currently doing an Assignment; however, I got some interesting output which confused me so much.
I am trying to sort the following dictionary:
result = {'A1': '9', 'A2': '14', 'A3': '16', 'A4': '0', 'B1': '53', 'B2': '267', 'B3': '75', 'B4': '22', 'C1': '19', 'C2': '407', 'C3': '171', 'C4': '56', 'C5': '10', 'D3': '47', 'D4': '34', 'D5': '10'}
My sorting code with Python 3 is the following : (only sorted by value)
sortedList = [v for v in sorted(result.values())]
The output is :
['0', '10', '10', '14', '16', '171', '19', '22', '267', '34', '407', '47', '53', '56', '75', '9']
which is not fully sorted. The output is quite strange.
Why it is happened like this?
I have used another dict to test like this:
testD = {'A':'5','B': '9','c': '8','d': '6'}
the output is right :
['5', '6', '8', '9']
Is there something wrong with my result dictionary or is there something I am missing?
Strings will be ordered with a lexical sort. To sort your data numerically, convert the values into integers first.
Strings are compared one character at a time, so '30' < '4' because '3' < '4'. You need to use a key parameter to get the comparison based on the numeric value, not the string characters.
Also, it's redundant to use a list comprehension on something that already returns a list.
sortedList = sorted(result.values(), key=int)
As the value of dictionary are string so there is lexical sorting based on ascii values.
As evident, you need the values to be sorted according to their integer values.
result = {'A1': '9', 'A2': '14', 'A3': '16', 'A4': '0', 'B1': '53', 'B2': '267', 'B3': '75', 'B4': '22', 'C1': '19', 'C2': '407', 'C3': '171', 'C4': '56', 'C5': '10', 'D3': '47', 'D4': '34', 'D5': '10'}
As mentioned in the comments by #AChampion, you can pass the sort value type by using key something like this :
sortedList = sorted(result.values(), key = int)
print(sortedList)
Or you can do something like this :
result_ints = dict((k,int(v)) for k,v in result.items())
sortedList = [str(v) for v in sorted(result_ints.values())]
print(sortedList)
Both of the above code snippets will result in :
['0', '9', '10', '10', '14', '16', '19', '22', '34', '47', '53', '56', '75', '171', '267', '407']
You can try this :
result = [{'A1': '9', 'A2': '14', 'A3': '16', 'A4': '0', 'B1': '53', 'B2': '267', 'B3': '75', 'B4': '22', 'C1': '19', 'C2': '407', 'C3': '171', 'C4': '56', 'C5': '10', 'D3': '47', 'D4': '34', 'D5': '10'}]
lst=[]
for item in result:
for key in item.keys():
lst.append(int(item.get(key)))
sortedList = [v for v in sorted(lst)]
print(sortedList)
Output: [0, 9, 10, 10, 14, 16, 19, 22, 34, 47, 53, 56, 75, 171, 267,
407]
I have a workable solution that returns a set:
>>> a = {'a': {'1', '2', '3'}, 'b': {'4', '5', '6'}, 'c': {'7', '8', '9'}}
>>> def flatten_nested(a):
temp = set(
[value for value_set in a.values() for value in value_set]
)
return temp | a.keys()
>>> flatten_nested(a)
>>> {'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c'}
I wondered if there was some itertools.chain-like function already built in to Python to do something similar?
I guess more simple is this:
>>> set.union(set(a), *a.values())
{'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c'}
Or, here's the same thing via the bound method:
>>> set(a).union(*a.values())
{'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c'}
If the values are already sets then wims answer is the simplest, but to work for iterables like a list, tuples etc.. you would have to map to a set i.e set(a).union(map(set, a.values()) or you could union the chain of all the values with the view of the keys:
from itertools import chain
def flatten_nested(a):
return a.keys() | chain(*a.values()) # a.viewkeys() python2
I have an array,
list = [['a', '2', '7'], ['b', '2', '9'],['a', '1', '4'],['c', '6', '1'],['b', '9', '9'],['a', '3', '2'],['c', '1', '5'],['b', '3', '7']]
I can write:
aList = [[row [1], row [2]] for row in list if row [0] == "a"]
bList = [[row [1], row [2]] for row in list if row [0] == "b"]
cList = [[row [1], row [2]] for row in list if row [0] == "c"]
to make a sub-array of second and third elements that has a specific first element i.e. ‘a’ , ‘b’ or ‘c’.
But I want to know what is the way to write one code that will do the work for all the first element.
Use a dictionary with the first item as key and rest of the items as values. collections.defaultdict will make this task a little easier for you, you can do this using a plain dict as well:
>>> from collections import defaultdict
>>> lst = [['a', '2', '7'], ['b', '2', '9'],['a', '1', '4'],['c', '6', '1'],['b', '9', '9'],['a', '3', '2'],['c', '1', '5'],['b', '3', '7']]
>>> d = defaultdict(list)
>>> for x in lst:
d[x[0]].append(x[1:])
#For plain dict this is going to be:
#d.setdefault(x[0], []).append(x[1:])
>>> d['a']
[['2', '7'], ['1', '4'], ['3', '2']]
>>> d['b']
[['2', '9'], ['9', '9'], ['3', '7']]
>>> d['c']
[['6', '1'], ['1', '5']]
import operator
L = [['a', '2', '7'], ['b', '2', '9'],['a', '1', '4'],['c', '6', '1'],['b', '9', '9'],['a', '3', '2'],['c', '1', '5'],['b', '3', '7']]
lists = {'a':[], 'b':[], 'c':[]}
g = operator.itemgetter(1,2)
for t in L:
lists[t[0]].append(g(t))
print('aList:', lists['a'])
print('bList:', lists['b'])
print('cList:', lists['c'])
Output:
aList: [('2', '7'), ('1', '4'), ('3', '2')]
bList: [('2', '9'), ('9', '9'), ('3', '7')]
cList: [('6', '1'), ('1', '5')]
Dictionary can do this work for you.
dict_list = {}
for row in list:
dict_list.setdefault(row[0],[])
dict_list[row[0]].append(row[1:])
setdefault will set the value as empty list [] if the key doesn't exist.
Output:
>>>dict_list
{'a': [['2', '7'], ['1', '4'], ['3', '2']],
'c': [['6', '1'], ['1', '5']],
'b': [['2', '9'], ['9', '9'], ['3', '7']]}
For example i have dict python
dict = {'a': '1', 'b': '2', 'c': '3'}
and array
arr = ['4', '5', '6']
I want add sequential value array to dict
dict1 = {'a': '4', 'b': '5', 'c': '6'}
Please suggest a specific solution.
>>> d = {'a': '1', 'b': '2', 'c': '3'}
>>> arr = ['4', '5', '6']
>>> dict(zip(sorted(d), arr))
{'a': '4', 'c': '6', 'b': '5'}
You can use zip:
>>> import string
>>> arr = ['4', '5', '6']
>>> # dict(zip(sorted(original_dict), arr))
>>> dict(zip(string.ascii_lowercase, arr))
{'b': '5', 'c': '6', 'a': '4'}
BTW, don't name a varialbe dict. It will shadows builtin type/function dict.
Not sure what you are trying to do, but the below code snippet does what you intend in your question.
import os
dict = {'a': '1', 'b': '2', 'c': '3'}
arr = ['4', '5', '6']
dict1 = {}
dictAsList = dict.items()
i = 0
for key in sorted(dict):
try:
dict1[key] = arr[i]
except:
pass
i = i+1
print dict1
Python dictionary doesn't have order. So I don't get what sequential means in dictionary.
If you just want to set all value to another value you can do like this.
d = {'a': '1', 'b': '2', 'c': '3'}
arr = ['4', '5', '6']
print dict(zip(d.keys(), arr))
#{'a': '4', 'c': '5', 'b': '6'}
If you want to set value as same order you can do like this.(You need change your data structure)
from collections import OrderedDict
d = OrderedDict([('a', '1'), ('b', '2'), ('c', '3')])
arr = ['4', '5', '6']
print dict(zip(d.keys(), arr))
#{'a': '4', 'c': '6', 'b': '5'}