Too many loops problem when loading a file - python

I would like to reduce the number of for loop when trying to loop into my file.
For example:
item =[{"item1": "man", "item2": "many", "item3":"mannyy"}]], [[{"item1": "power", "item2": "cow", "item3":"king"}]], [[{"item1": "man", "item2": "many", "item3":"mannyy"}]], [[{"item1": "power", "item2": "cow", "item3":"king"}]
for i, x in enumerate(item):
print(x["item1"])
I am wondering whether is there a possibility to reduce the number of loop while at the same time could get the enumerate for "i", "ii", "iii" too? I do not wish to use too many for loops

You can try the following code..
item = [{'item2': 'many', 'item1': 'man', 'item3': 'mannyy'},{'item2': 'cow', 'item1': 'power', 'item3': 'king'}, {'item2': 'many', 'item1': 'man', 'item3': 'mannyy'}, {'item2': 'cow', 'item1': 'power', 'item3': 'king'}]
for i in a:
print(i['item1'])

Related

Calculating the semantic descriptor of a nested list

I am trying to calculate the semantic description of a nested list to turn it into a nested dictionary. First I got distinct_words, each word of it will be the keys of my final dictionary.
def build_semantic_descriptors(sentences):
flat_list = [term for group in sentences for term in group]
distinct_words = set(flat_list)
d = {}
for row in sentences:
for words in row:
if words not in d:
d[words] = 1
else:
d[words] += 1
if __name__ == '__main__':
x = [["i", "am", "a", "sick", "man"],
["i", "am", "a", "spiteful", "man"],
["i", "am", "an", "unattractive", "man"],
["i", "believe", "my", "liver", "is", "diseased"],
["however", "i", "know", "nothing", "at", "all", "about", "my",
"disease", "and", "do", "not", "know", "for", "certain", "what", "ails", "me"]]
print(build_semantic_descriptors(x))
EXPECTED OUTPUT: {'i': {'am': 3, 'a': 2, 'sick': 1, 'man': 3, 'spiteful': 1, 'an': 1, 'unattractive': 1, 'believe': 1, 'my': 2, 'liver': 1, 'is': 1, 'diseased': 1, 'however': 1, 'know': 1, 'nothing': 1, 'at': 1, 'all': 1, 'about': 1, 'disease': 1, 'and': 1, 'do': 1, 'not': 1, 'for': 1, 'certain': 1, 'what': 1, 'ails': 1, 'me': 1}, 'am': {'i': 3, 'a': 2, 'sick': 1, 'man': 3, 'spiteful': 1, 'an': 1, 'unattractive': 1}, etc...}
At this moment this is my code. I already got the words I want as the keys, but I don't know how to count the words related to them and put into the final dictionary, I've tried using the counter above, but what it does is calculate the overall value of appearences.
Thanks in advance for any help.
Try this:
from collections import defaultdict
from itertools import product
def build_semantic_descriptors(sentences):
d = defaultdict(lambda: defaultdict(int))
for sentence in sentences:
should_skip_key = True
for (key, word) in product(sentence, sentence):
if key == word and should_skip_key:
should_skip_key = False
continue
d[key][word] += 1
return d
if __name__ == '__main__':
x = [["i", "am", "a", "sick", "man"],
["i", "am", "a", "spiteful", "man"],
["i", "am", "an", "unattractive", "man"],
["i", "believe", "my", "liver", "is", "diseased"],
["however", "i", "know", "nothing", "at", "all", "about", "my",
"disease", "and", "do", "not", "know", "for", "certain", "what", "ails", "me"]]
print(build_semantic_descriptors(x))
You need to loop each sentence twice, in order to get each word for each key. For this you can use itertools.product.
Also note that I use here collections.defaultdict which you should read about, it is a nice utility that sets the dictionary with a default if the key does not exist (allowing to skip the check that you had)

How to create and print a Dictionary that has keys as the names in list and their values as number of times the name appears on the list

I have a list of names:
list = ['Ginger', 'Willow', 'Scout', 'Roscoe', 'Bear', 'Kobe', 'Baxter', 'Zara', 'Fiona', 'Milo', 'Oakley', 'Dakota', 'Prince', 'Bruno', 'Panda', 'Dexter', 'Ziggy', 'Roscoe', 'Lucy', 'Boomer', 'Fiona', 'Ella', 'Emma', 'Oakley']
Using this list, I've created the following dictionary:
listA = {"G": "Ginger", "W": "Willow", "S": "Scout", "R": ["Roscoe", "Roscoe"], "B": ["Bear", "Baxter", "Bruno", "Boomer"], "K": "Kobe", "Z": ["Zara", "Ziggy"], "F": ["Fiona", "Fiona"], "M": "Milo", "O": ["Oakley", "Oakley"], "D": ["Dakota", "Dexter"], "P": ["Prince", "Panda"], "L": "Lucy", "E": ["Ella", "Emma"]}
Printing the keys from the dictionary:
for key in listA.keys():
print(key)
I get:
G
W
S
R
B
K
Z
F
M
O
D
P
L
E
How can I get the number of times that each name appears in the list?
You don't need listA; collections.Counter does exactly what you're looking for.
import collections
data = ['Ginger', 'Willow', 'Scout', 'Roscoe', 'Bear', 'Kobe', 'Baxter', 'Zara', 'Fiona', 'Milo', 'Oakley', 'Dakota', 'Prince', 'Bruno', 'Panda', 'Dexter', 'Ziggy', 'Roscoe', 'Lucy', 'Boomer', 'Fiona', 'Ella', 'Emma', 'Oakley']
counter = collections.Counter(data)
print(counter) # Prints counter object.
counter_as_dict = dict(counter) # Can be transformed into a dictionary using dict().
print(counter_as_dict.keys()) # Prints names in dictionary.

Reorganize a list of dictionaries

Assuming I have the following:
[
{"sku": "ZZZ", "name":"None name","shelf": 10},
{"sku": "AAA", "name":"One name","shelf": 10},
{"sku": "BBB", "name":"The name", "shelf": None},
{"sku": "CCC", "name":"A name"}
]
I am trying to find the best (most elegant maybe) way to:
Add "shelf": 'Default' when missing or set to None
Split the list per shelf, so the one above should give out two named lists: one for Default and one for '10'
This is the desired output:
[
{"10":[
{"sku": "ZZZ", "name":"None name"},
{"sku": "AAA", "name":"One name"}]
},
{"default":[
{"sku": "CCC", "name":"A name"},
{"sku": "BBB", "name":"The name"]
}
]
Using pydash.collections.for_each(initial_list,reorganize) I can sort the first problem, but I am not sure how to deal with the second.
def reorganize(x):
if 'shelf' not in x: x['shelf'] = 'default'
if x['shelf'] is None: x['shelf'] = 'default'
I also do not thing this is the best way to solve the problem.
Reason for pivoting the list is because I need to call an API which needs the shelf as parameter and cannot accept multiple shelf at the same time (but accepts multiple SKUs).
input_list = [
{"sku": "ZZZ", "name":"None name","shelf": 10},
{"sku": "AAA", "name":"One name","shelf": 10},
{"sku": "BBB", "name":"The name", "shelf": None},
{"sku": "CCC", "name":"A name"}
]
output_dict = {}
for d in input_list:
output_dict.setdefault(d.pop('shelf', 'default') or 'default', []).append(d)
output_dict is:
{10: [{'sku': 'ZZZ', 'name': 'None name'}, {'sku': 'AAA', 'name': 'One name'}], 'default': [{'sku': 'BBB', 'name': 'The name'}, {'sku': 'CCC', 'name': 'A name'}]}
Let's explain the code:
pop returns the shelf entry and removes it from the dictionary;
if shelf is not present, pop returns the default value, i.e. its
second (optional) argument ('default' in this case). The or is
used to handle the cases when shelf is present, but with a None
or '' value: in this case, default is used.
setdefault returns the value of the dictionary with key equal to
the first argument, or it returns the second argument if the key is
not present.
append adds the current dictionary (with shelf entry removed by pop) to the list corresponding to its shelf value.
lst = [
{"sku": "ZZZ", "name":"None name","shelf": 10},
{"sku": "AAA", "name":"One name","shelf": 10},
{"sku": "BBB", "name":"The name", "shelf": None},
{"sku": "CCC", "name":"A name"}
]
lst2 = list()
for dct in lst:
v = dct.pop("shelf", None) or "default"
for d in lst2:
if d.get(v):
d[v].append(dct)
break
else:
lst2.append({v: [dct]})
print(lst2)
Output:
[{10: [{'sku': 'ZZZ', 'name': 'None name'},
{'sku': 'AAA', 'name': 'One name'}]},
{'default': [{'sku': 'BBB', 'name': 'The name'},
{'sku': 'CCC', 'name': 'A name'}]}]
Breaking it down:
Define a list, lst2, to become the output list.
Iterate through the dictionaries of lst, and define a variable, v,
to check if the value of the soon-to-be-created-dictionary should be the value of the current dictionary's "shelf" key, or "default".
Iterate through each dictionary of the lst2. If coresponding key are found, append the dictionary to the key of the lst2.
my take on the question, with pandas:
df = pd.DataFrame([
{"sku": "ZZZ", "name":"None name","shelf": 10},
{"sku": "AAA", "name":"One name","shelf": 10},
{"sku": "BBB", "name":"The name", "shelf": None},
{"sku": "CCC", "name":"A name"}
])
df.shelf = df.shelf.fillna('default')
for shelf, skus in df.groupby('shelf').sku.apply(list).items():
print(shelf, "=>", skus)
>>>
10.0 => ['ZZZ', 'AAA']
default => ['BBB', 'CCC']

Automatically Creating List of Dictionaries Based Upon Two Lists of Equal Length with Python

There are two lists:
customer_list = ["A7", "A8", "A9", "A10", "A11"]
customer_index = ["8", "9", "10", "11", "12"]
The goal is to create the following:
final_list = [
{
"kind": "report#variable",
"type": "A7",
"value": line[8]}
,
{
"kind": "report#variable",
"type": "A8",
"value": line[9]}
,
{
"kind": "report#variable",
"type": "A9",
"value": line[10]}
,
{
"kind": "report#variable",
"type": "A10",
"value": line[11]}
,
{
"kind": "report#variable",
"type": "A11",
"value": line[12]}
]
I tried to use the following Python code, but it did not work:
def create_final_list(list_1, list_2):
new_list = []
list_prefix = '{"kind": "report#variable",'
for num in list_1:
for val in list_2:
list_1_num = ' "type": ' + num
list_2_val = ' "value": ' + val
new_list.append(list_prefix + list_1_num + list_2_val)
return new_list
How does one automatically create a list of Dictionaries based upon two lists of equal length and the desired format as in the above example?
This is not a JSON; but a list of dictionaries which you create in a list-comprehension with zip():
customer_list = ["A7", "A8", "A9", "A10", "A11"]
customer_index = ["8", "9", "10", "11", "12"]
line = [1,2,3,4,5,6,7,8,9,101,11,12,13,14] # assume this `line` list
res = [{"kind": "report#variable", "type": x, "value": line[int(y)]} for x, y in zip(customer_list, customer_index)]
As is in the comments, you can then do:
json.dumps(res)
..to convert res to a JSON string.
Since pandas is tagged, adding another way using a dataframe and groupby:
df = pd.DataFrame({"kind": "report#variable","type":customer_list,"value":customer_index})
final = [g.droplevel(0).to_dict() for _,g in df.stack().groupby(level=0)]
[{'kind': 'report#variable', 'type': 'A7', 'value': '8'},
{'kind': 'report#variable', 'type': 'A8', 'value': '9'},
{'kind': 'report#variable', 'type': 'A9', 'value': '10'},
{'kind': 'report#variable', 'type': 'A10', 'value': '11'},
{'kind': 'report#variable', 'type': 'A11', 'value': '12'}]
Try
lis = []
for i in range(len(customer_index)):
dic = {"type" : customer_list[i], "value" : customer_index[i]}
lis.append(dic)
This outputs
[{'type': 'A7', 'value': '8'},
{'type': 'A8', 'value': '9'},
{'type': 'A9', 'value': '10'},
{'type': 'A10', 'value': '11'},
{'type': 'A11', 'value': '12'}]
As in your code, if you want line[8], do line[customer_index[i]] instead of customer_index[i] during dictionary initialization. Also, add 1 more key of kind in the dictionary, as per your requirement.
The above code works only if both customer_list and customer_index are of equal length, because the loop iterates n number of times, where n is the equal length of the list.

Picking certain set of dictionary

I tried to find the solution everywhere but I couldn't find the way to solve this problem. Suppose I have multiple dictionaries in a list:
[
{"Type": "A", "Name": "Sam"},
{"Type": "A", "Name": "Apple"},
{"Type": "B", "Name": "Sam"},
{"Type": "C", "Name": "Apple"},
{"Type": "C"}
]
What I need are the dictionaries that have 'Type' == 'A'.
The result I am trying to get is:
[{"Type": "A", "Name": "Sam"}, {"Type": "A", "Name": "Apple"}]
Is there any way I could achieve this? Any help or any direction into solving this problem would be great.
Go through your list and take all dictionaries with a Type of A:
>>> data = [{"Type": "A", "Name": "Sam"},{"Type":"A", "Name":"Apple"},{"Type": "B", "Name": "Sam"},{"Type":"C", "Name":"Apple"},{"Type":"C"}]
>>> [d for d in data if d.get('Type') == 'A']
[{'Name': 'Sam', 'Type': 'A'}, {'Name': 'Apple', 'Type': 'A'}]
Using dict.get() ensures that it works for dicts without the key Type:
data = [{"Type": "A", "Name": "Sam"},
{"Type":"A", "Name":"Apple"},
{"Type": "B", "Name": "Sam"},
{"Type":"C", "Name":"Apple"},
{"Type":"C"},
{}]
>>> [d for d in data if d.get('Type') == 'A']
[{'Name': 'Sam', 'Type': 'A'}, {'Name': 'Apple', 'Type': 'A'}]
because:
get(key[, default])
Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.
>>> a
[{'Type': 'A', 'Name': 'Sam'}, {'Type': 'A', 'Name': 'Apple'}, {'Type': 'B', 'Name': 'Sam'}, {'Type': 'C', 'Name': 'Apple'}, {'Type': 'C'}]
>>> b = [x for x in a if x['Type']=='A']
>>> b
[{'Type': 'A', 'Name': 'Sam'}, {'Type': 'A', 'Name': 'Apple'}]
[d for d in d_list if d.get('Type') == 'A']
This is almost definitely not the most pythonic way of doing it, but if you need a quick and dirty solution, I believe it works.
def filterDictionaries(dictionaries, type):
filteredDicts = []
for dict in dictionaries:
if 'Type' in dict:
if dict['Type] == type:
filteredDicts += dict
return filteredDicts

Categories