Now, I wanna convert an array to a dict like this:
dict = {'item0': arr[0], 'item1': arr[1], 'item2': arr[2]...}
How to solve this problem elegantly in python?
You could use enumerate and a dictionary comprehension:
>>> arr = ["aa", "bb", "cc"]
>>> {'item{}'.format(i): x for i,x in enumerate(arr)}
{'item2': 'cc', 'item0': 'aa', 'item1': 'bb'}
Suppose we have a list of ints:
We can use a dict comprehension
>>> l = [3, 2, 4, 5, 7, 9, 0, 9]
>>> d = {"item" + str(k): l[k] for k in range(len(l))}
>>> d
{'item5': 9, 'item4': 7, 'item7': 9, 'item6': 0, 'item1': 2, 'item0': 3, 'item3': 5, 'item2': 4}
simpleArray = [ 2, 54, 32 ]
simpleDict = dict()
for index,item in enumerate(simpleArray):
simpleDict["item{0}".format(index)] = item
print(simpleDict)
Ok, first line Is the input, second line is an empty dictionary. We will fill it on the fly.
Now we need to iterate, but normal iteration as in C is considered non Pythonic. Enumerate will give the index and the item we need from the array. See this: Accessing the index in Python 'for' loops.
So in each iteration we will be getting an item from array and inserting in the dictionary with a key from the string in brackets. I'm using format since use of % is discouraged. See here: Python string formatting: % vs. .format.
At last we will print. Used print as function for more compatibility.
you could use a dictionary comprehension
eg.
>>> x = [1,2,3]
>>> {'item'+str(i):v for i, v in enumerate(x)}
>>> {'item2': 3, 'item0': 1, 'item1': 2}
Use dictionary comprehension: Python Dictionary Comprehension
So it'll look something like:
d = {"item%s" % index: value for (index, value) in enumerate(arr)}
Note the use of enumerate to give the index of each value in the list.
You can also use the dict() to construct your dictionary.
d = dict(('item{}'.format(i), arr[i]) for i in xrange(len(arr)))
Using map, this could be solved as:
a = [1, 2, 3]
d = list(map(lambda x: {f"item{x[0]}":x[1]}, enumerate(a)))
The result is:
[{'item0': 1}, {'item1': 2}, {'item2': 3}]
Related
Reading about data structures and have a question.
This is a dictionary:
example = {'the': 8,
'metal': 8,
'is': 23,
'worth': 3,
'many': 3,
'dollars': 2,
'right': 2}
How to store to a variable the value of a key/value pair by order?
For example, how to store the value of the third pair, which is 23?
Tried this, which is not correct:
for k in example:
if k == 3:
a_var = example(k)
If you know the key/values have been inserted in the correct order, you can use islice() to get the third key/value pair. This has the benefit of not needing to create a whole list of values and is a bit simpler than explicitly writing a loop:
from itertools import islice
example = {
'the': 8,
'metal': 8,
'is': 23,
'worth': 3,
'many': 3,
'dollars': 2,
'right': 2
}
key, val = next(islice(example.items(), 2, None))
# 'is', 23
If you only want the value instead of the key/value pair, then of course you can pass values() instead of items() to islice():
val = next(islice(example.values(), 2, None))
# 23
This does what you need:
example = {'the': 8,
'metal': 8,
'is': 23,
'worth': 3,
'many': 3,
'dollars': 2,
'right': 2}
k=0
for key in example:
k+=1
if k == 3:
a_var = example[key]
print(a_var)
Output:
23
If you really think you need this:
def find( example, ordinal):
for k,value in enumerate(example.values()):
if k == ordinal:
return value
or
def find( example, ordinal):
return list(example.values())[ordinal]
a_var=example[list(example.keys())[3-1]]
I have a number of lists as follows:
list1 = ['a_1','a_2','b_17','c_19']
list2 = ['aa_1','a_12','b_15','d_39']
list3 = ['a_1','a_200','ba_1','u_0']
I wish to generate a histogram based on the labels, ignoring the numbering, that is, a has 4 entries over all the lists, ba 1 entry, u has 1 entry, and so on. The labels, are file names from a specific folder, before adding the numbers, so it is a finite known list.
How can I perform such a count without a bunch of ugly loops? Can I use unique here, somehow?
You cannot acheive it without a loop. But you can instead use list comphrension to make it into a single line. Something like this.
list1 = ['a_1','a_2','b_17','c_19']
list2 = ['aa_1','a_12','b_15','d_39']
list3 = ['a_1','a_200','ba_1','u_0']
lst = [x.split('_')[0] for x in (list1 + list2 + list3)]
print({x: lst.count(x) for x in lst})
You can use a defaultdict initialized to 0 to count the occurrence and get a nice container with the required information.
So, define the container:
from collections import defaultdict
histo = defaultdict(int)
I'd like to split the operation into methods.
First get the prefix from the string, to be used as key in the dictionary:
def get_prefix(string):
return string.split('_')[0]
This works like
get_prefix('az_1')
#=> 'az'
Then a method to update de dictionary:
def count_elements(lst):
for e in lst:
histo[get_prefix(e)] += 1
Finally you can call this way:
count_elements(list1)
count_elements(list2)
count_elements(list3)
dict(histo)
#=> {'a': 5, 'b': 2, 'c': 1, 'aa': 1, 'd': 1, 'ba': 1, 'u': 1}
Or directly
count_elements(list1 + list2 + list3)
To get the unique count, call it using set:
count_elements(set(list1 + list2 + list3))
dict(histo)
{'ba': 1, 'a': 4, 'aa': 1, 'b': 2, 'u': 1, 'd': 1, 'c': 1}
Assuming I have the following structure:
listoflist = [[0,1,2,3,4],[2,4,2,3,4],[3,4,5,None,3],...]
Assuming I have:
headers = ["A","B","C","D","E"]
I want to convert each to:
listofobj = [{"A":0,"B":2,"C":3,"D":4,"E":5},{"A":2,"B":4,"C":2,"E":4}]
What is the best way to do this?
Note that D: does not show up for the 3rd dictionary in the converted list because it is None. Am looking for the most optimal way/quickest performance for this.
You can use list comprehension to perform an operation on each element of a list, the zip builtin function to match each element of headers against the corresponding element in listoflist, and the dict builtin function to convert each of those into a dictionary. So, the code you want is
listofobj = [dict(zip(headers, sublist)) for sublist in listoflist]
Removing None values is probably best done in another function:
def without_none_values(d):
return {k:d[k] for k in d if d[k] is not None}
With that function, we can complete the list with
listofobj = [without_none_values(dict(zip(headers, sublist))) for sublist in listoflist]
Easy to do in Python >= 2.7 using dictionary comprehension:
listofobj = [
{ k: v for k, v in zip(headers, sublist) if v is not None }
for sublist in listoflist
]
In Python 2.6 one needs to use dict:
listofobj = [
dict((k, v) for k, v in zip(headers, sublist) if v is not None)
for sublist in listoflist
]
I would iterate through each list, and zip it with the list of headers.
headers = ["A","B","C","D","E"]
listoflist = [[0,1,2,3,4],[2,4,2,3,4],[1,2,3,4,4],[5,6,7,8,9],[0,9,7,6,5]]
[dict(zip(headers, sublist)) for sublist in listoflist]
Output
[{'A': 0, 'C': 2, 'B': 1, 'E': 4, 'D': 3},
{'A': 2, 'C': 2, 'B': 4, 'E': 4, 'D': 3},
{'A': 1, 'C': 3, 'B': 2, 'E': 4, 'D': 4},
{'A': 5, 'C': 7, 'B': 6, 'E': 9, 'D': 8},
{'A': 0, 'C': 7, 'B': 9, 'E': 5, 'D': 6}]
Create a Pandas Series object from each of the lists in your listoflist, using headers as the index.
Then drop None values using dropna() method. And finally create a dictionary from each Series.
import pandas as pd
listofobj = [dict(pd.Series(x, index = headers).dropna()) for x in listoflist]
[x for x in l if x is not None] keeps all values that are not None
We enumerate over headers and access the element at the corresponding index in each sublist of listoflist using l[ind].
if l[ind] will be True if the value is not None so we use that element as a key or else ignore it if the value is None.
list_of_obj = [dict(zip([x for ind ,x in enumerate(headers) if l[ind] is not None],[x for x in l if x is not None])) for l in listoflist]
dico = {"dico": {1:"bailler",2:"bailler",3:"percer",4:"calculer",5:"calculer",6:"trouer",7:"bailler",8:"découvrir",9:"bailler",10:"miser",11:"trouer",12:"changer"}}
I have a big dictionary of dictionaries like that. I want to put identic elements together in sets. So create a kind of condition which will say if the values of "dico" are equal put them in a set():
b=[set(1,2,7,9),set(3),set(4,5),set(6,11),set(8),set(10),set(12)]
I don't know if that question has already been asked but as a new pythonner I don't have all the keys... ^^
Thank you for you answers
I would reverse your dictionary and have the value a set(), then return all the values.
>>> from collections import defaultdict
>>>>my_dict= {"dico": {1:"bailler",2:"bailler",3:"percer",4:"calculer",5:"calculer",6:"trouer",7:"bailler",8:"découvrir",9:"bailler",10:"miser",11:"trouer",12:"changer"}}
>>> my_other_dict = defaultdict(set)
>>> for dict_name,sub_dict in my_dict.iteritems():
for k,v in sub_dict.iteritems():
my_other_dict[v].add(k) #the value, i.e. "bailler" is now the key
#e.g. {"bailler":set([1,2,9,7]),...
>>> [v for k,v in my_other_dict.iteritems()]
[set([8]), set([1, 2, 9, 7]), set([3]), set([4, 5]), set([12]), set([11, 6]), set([10])]
Of course as cynddl has pointed out, if your index in a list will always be the "key", simply enumerate a list and you won't have to store original data as a dictionary, nor use sets() as indices are unique.
You should write your data this way:
dico = ["bailler", "bailler", "percer", "calculer", "calculer", "trouer", "bailler", "découvrir", "bailler", "miser", "trouer", "changer"]
If you want to count the number of identic elements, use collections.Counter:
import collections
counter=collections.Counter(dico)
print(counter)
which returns a Counter object:
Counter({'bailler': 4, 'calculer': 2, 'trouer': 2, 'd\xc3\xa9couvrir': 1, 'percer': 1, 'changer': 1, 'miser': 1})
The dict.setdefault() method can be handy for tasks like this, as well as dict.items() which iterates through the (key, value) pairs of the dictionary.
>>> dico = {"dico": {1:"bailler",2:"bailler",3:"percer",4:"calculer",5:"calcul
er",6:"trouer",7:"bailler",8:"découvrir",9:"bailler",10:"miser",11:"trouer",12:"
changer"}}
>>> newdict = {}
>>> for k, subdict in dico.items():
... newdict[k] = {}
... for subk, subv in subdict.items():
... newdict[k].setdefault(subv, set()).add(subk)
...
>>> newdict
{'dico': {'bailler': {1, 2, 9, 7}, 'miser': {10}, 'découvrir': {8}, 'calculer':
{4, 5}, 'changer': {12}, 'percer': {3}, 'trouer': {11, 6}}}
>>> newdict['dico'].values()
dict_values([{1, 2, 9, 7}, {10}, {8}, {4, 5}, {12}, {3}, {11, 6}])
dict1={'s1':[1,2,3],'s2':[4,5,6],'a':[7,8,9],'s3':[10,11]}
how can I get all the value which key is with 's'?
like dict1['s*']to get the result is dict1['s*']=[1,2,3,4,5,6,10,11]
>>> [x for d in dict1 for x in dict1[d] if d.startswith("s")]
[1, 2, 3, 4, 5, 6, 10, 11]
or, if it needs to be a regex
>>> regex = re.compile("^s")
>>> [x for d in dict1 for x in dict1[d] if regex.search(d)]
[1, 2, 3, 4, 5, 6, 10, 11]
What you're seeing here is a nested list comprehension. It's equivalent to
result = []
for d in dict1:
for x in dict1[d]:
if regex.search(d):
result.append(x)
As such, it's a little inefficient because the regex is tested way too often (and the elements are appended one by one). So another solution would be
result = []
for d in dict1:
if regex.search(d):
result.extend(dict1[d])
>>> import re
>>> from itertools import chain
def natural_sort(l):
# http://stackoverflow.com/a/4836734/846892
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
return sorted(l, key = alphanum_key)
...
Using glob pattern, 's*':
>>> import fnmatch
def solve(patt):
keys = natural_sort(k for k in dict1 if fnmatch.fnmatch(k, patt))
return list(chain.from_iterable(dict1[k] for k in keys))
...
>>> solve('s*')
[1, 2, 3, 4, 5, 6, 10, 11]
Using regex:
def solve(patt):
keys = natural_sort(k for k in dict1 if re.search(patt, k))
return list(chain.from_iterable( dict1[k] for k in keys ))
...
>>> solve('^s')
[1, 2, 3, 4, 5, 6, 10, 11]
I tried below hope it help you, by getting the keys of dictionary and then if the first index of the key is your start with character then extend the list with the key dictionary list.
n='s' # your start with character
result=[] # your output
for d in dict1.keys():
if n == d[0]:
result.extend(dict1[d])
print result