Reputation: 4991
I have the following list:
x=['a','3','4','b','1','2','c','4','5']
How can i make the following dictionary:
b = {'a':[3,4],'b':[1,2],'c':[4,5]}
I tried the following:
Category = defaultdict(int)
for i in a:
if Varius.is_number(i)==False:
Category[i]=[]
keys.append(i)
else:
Category[keys(i)] = i
The keys are created but after i have problem to insert the values.(is_number
is a function which check if the value of the list is number or string).First day away of MATLAB.First day in Python..
Upvotes: 5
Views: 5258
Reputation: 107287
You can use itertools.groupby
:
>>> from itertools import groupby
>>> l=[list(g) for k,g in groupby(x,lambda x : x.isalpha())]
>>> p=[l[i:i+2] for i in range(0,len(l),2)]
>>> {i[0]:map(int,j) for i,j in p}
{'a': [3, 4], 'c': [4, 5], 'b': [1, 2]}
Upvotes: 2
Reputation: 250961
Using itertools.groupby
and some iterator stuff:
>>> from itertools import groupby
>>> it = (next(g) if k else map(int, g) for k, g in groupby(x, str.isalpha))
>>> {k: next(it) for k in it}
{'a': [3, 4], 'c': [4, 5], 'b': [1, 2]}
Here the first iterator will yield something like:
>>> [next(g) if k else map(int, g) for k, g in groupby(x, str.isalpha)]
['a', [3, 4], 'b', [1, 2], 'c', [4, 5]]
Now as this iterator is going to yield key-value alternately, we can loop over this iterator and get the next item from it(i.e the value) using next()
>>> it = (next(g) if k else map(int, g) for k, g in groupby(x, str.isalpha))
>>> for k in it:
print k,'-->' ,next(it)
...
a --> [3, 4]
b --> [1, 2]
c --> [4, 5]
There's another way to consume this iterator that is using zip
, but it's a little hard to understand IMO:
>>> it = (next(g) if k else map(int, g) for k, g in groupby(x, str.isalpha))
>>> dict(zip(*[it]*2))
{'a': [3, 4], 'c': [4, 5], 'b': [1, 2]}
Upvotes: 1
Reputation: 120608
Simple solution using just dict
and list
:
>>> category = {}
>>> for i in x:
... if i.isalpha():
... items = category[i] = []
... elif category:
... items.append(i)
...
>>> print(category)
{'c': ['4', '5'], 'a': ['3', '4'], 'b': ['1', '2']}
Upvotes: 0
Reputation: 176830
If the key/value entries in your list x
are evenly spaced, here's an alternative way to build the dictionary. It uses a few of Python's built in features and functions:
>>> keys = x[::3]
>>> values = [map(int, pair) for pair in zip(x[1::3], x[2::3])]
>>> dict(zip(keys, values))
{'a': [3, 4], 'b': [1, 2], 'c': [4, 5]}
To explain what's being used here:
x
: x[start:stop:step]
zip
takes two lists and makes a list of tuples containing the n-th elements of each listmap(int, pair)
turns a tuple of digit strings into a list of integersvalues
is constructed with list comprehension - the map
function is applied to each pairdict
turns a list of pairs into dictionary keys/valuesUpvotes: 4
Reputation: 24324
Assuming you have a key on the first positions of your list (x
) and that after a letter, there will be a number:
from collections import defaultdict
x=['a','3','4','b','1','2','c','4','5']
key = x[0]
Category = defaultdict(int)
for i in x:
if i.isalpha():
key = i;
else:
Category[key].append(i)
print Category
Upvotes: 1
Reputation: 5855
Here an example that actually uses the feature that defaultdict
provides over the normal dict
:
from collections import defaultdict
x=['a','3','4','b','1','2','c','4','5']
key='<unknown>' # needed if the first value of x is a number
category = defaultdict(list) # defaultdict with list
for i in x:
if i.isalpha():
key = i;
else:
category[key].append(i) # no need to initialize with an empty list
print category
Also: you should use lower case names for class instances. Uppercase names are usually reserved for classes. Read pep8 for a style guide.
Upvotes: 4