Why is not looping? - python

I'm learning python and I'm not sure why the output of the below code is only "False" and not many "false" if I created a loop and the list of dict have 5 elements.
I was expect an ouput like
"False"
"False"
"False"
"False"
"False"
movies = [{
"name": "Usual Suspects"
}, {
"name": "Hitman",
}, {
"name": "Dark Knight",
},{
"name": "The Choice",
}, {
"name": "Colonia",}
]
def peliMayor(p):
index= -1
for n in movies:
index= index + 1
if (movies[index]['name'] == p):
return print("True")
else:
return print("False")
peli = "Thriller"
peliMayor(peli)

You should remove return from your for-loop as it breaks your loop.
Also, the if-else statement is not required. You can print the boolean value directly from the comparison movies[index]['name'] == p
def peliMayor(p):
index= -1
for n in movies:
index= index + 1
print(movies[index]['name'] == p)
movies = [{'name': 'Usual Suspects'}, {'name': 'Hitman'},
{'name': 'Dark Knight'}, {'name': 'The Choice'},
{'name': 'Colonia'}]
peli = 'Thriller'
peliMayor(peli)

You should remove return from loop. The following code will help you. Thanks.
movies = [{'name': 'Usual Suspects'}, {'name': 'Hitman'},
{'name': 'Dark Knight'}, {'name': 'The Choice'},
{'name': 'Colonia'}]
def peliMayor(p):
index = -1
for n in movies:
index = index + 1
if movies[index]['name'] == p:
print 'True'
else:
print 'False'
peli = 'Thriller'
peliMayor(peli)

Related

How to build a nested dictionary of varying depth using for loop?

Given a Pandas table of thousands of rows, where the left most spaces of a row determine if it's a sub structure of the above row or not.
Parameter | Value
'country' 'Germany'
' city' 'Berlin'
' area' 'A1'
' city' 'Munchen'
' comment' 'a comment'
'country' 'France'
' city' 'Paris'
' comment' 'a comment'
'state' 'California'
' comment' '123'
Where I have information about if a parameter is a list or not.
{
'country': list,
'city': list
'state': list
}
I would want to create the following nested structure
{
"country": [
{
"Germany": {
"city": [
{
"Berlin": {
"area": "A1"
}
},
{
"Munchen": {
"comment": "a comment"
}
}
]
}
},
{
"France": {
"city": [
{
"Paris": {
"comment": "a comment"
}
}
]
}
}
],
"state": [
{
"California": {
"comment": 123
}
}
]
}
Since the knowledge about what level the sub structure depends on only the row before, I thought that a for loop would be good. But I am clearly missing something fundamental about creating nested dictionaries using for loops. It could be a recursive solution as well, but I am unsure if it would be easier here.
This is my current attempt which is obviously a mess.
import pandas as pd
params = ['country',' city',' area',' city',' comment','country',' city',' comment','state',' comment']
vals = ['Germany','Berlin','A1','Munich','acomment','France','Paris','acomment','California','123']
conf = {'country':'list','city':'list'}
df = pd.DataFrame()
df['param'] = params
df['vals']= vals
output_dict = dict()
level_path = dict()
for param,vals in df.values:
d = output_dict
hiearchy_level = sum( 1 for _ in itertools.takewhile(str.isspace,param)) ## Count number of left most spaces
param = param.lstrip()
if hiearchy_level > 0:
base_path = level_path[str(hiearchy_level-1)]
else:
base_path = []
path = base_path + [param]
for p in path:
if p in conf: ## It should be a list
d.setdefault(p,[{}])
d = d[p][-1] ## How to understand if I should push a new list element or enter an existing one?
else:
d.setdefault(p,{})
d = d[p]
d[param] = vals
level_path[str(hiearchy_level)] = path
and the output being
{'country': [{'country': 'France',
'city': [{'city': 'Paris',
'area': {'area': 'A1'},
'comment': {'comment': 'a comment'}}]}],
'state': {'state': 'California', 'comment': {'comment': '123'}}}
I don't understand how I should be able to step in and out of the list elements in the for loop, knowing if I should push a new dictionary or enter an already existing one.
Any input on what I am missing would be appreciated.

Django dictionary with the same value

I'm trying to create a dictionary with some specific values but it gets the same values multiple times:
readers = Readers.objects.all()
count = 0
readersResult = {}
test = {
"avatar": "",
"firstName": "",
"percent": "",
"lastName": ""
}
for reader in readers:
test["percent"] = "value from another place"
test["firstName"] = reader.firstName
test["lastName"] = reader.lastName
test["avatar"] = reader.avatar
print("TEST: ", test)
readersResult[count] = test
count = count + 1
print("RESULT":, readersResult)
My output is:
web_1 | TEST: {'avatar': '/images/avatars/71.png', 'firstName': 'abc', 'percent': '37.08999158957107', 'lastName': 'def'}
web_1 | TEST: {'avatar': '/images/avatars/61.png', 'firstName': 'abc', 'percent': '4.037005887300253', 'lastName': 'def'}
web_1 | RESULT: {0: {'avatar': '/images/avatars/61.png', 'firstName': 'abc', 'percent': '4.037005887300253', 'lastName': 'def'}, 1: {'avatar': '/images/avatars/61.png', 'firstName': 'abc', 'percent': '4.037005887300253', 'lastName': 'def'}}
What am I doing wrong?
Here, in your code, you make a dict named test, and then in each loop iteration you add it again to the readersResult.
test = {
"avatar": "",
"firstName": "",
"percent": "",
"lastName": ""
}
for reader in readers:
test["percent"] = "value from another place"
test["firstName"] = reader.firstName
test["lastName"] = reader.lastName
test["avatar"] = reader.avatar
print("TEST: ", test)
readersResult[count] = test
count = count + 1
You need to create a new dict with each loop iteration. So exchange this part of your code to this:
for reader in readers:
test = {}
test["percent"] = "value from another place"
test["firstName"] = reader.firstName
test["lastName"] = reader.lastName
test["avatar"] = reader.avatar
print("TEST: ", test)
readersResult[count] = test
count = count + 1
PS: You don't need to use the below code to define the keys in the dictionary and then set its values somewhere else. So you can change:
teste = {
"avatar": [],
"firstName": [],
"percent": [],
"lastName": []
}
with:
test = {}
You are assigning the same dictionary (test) to multiple entries in readersResult, as opposed to making a new one for each reader.
You can use a list as the dictionary value:
readers = Readers.objects.all()
count = 0
readersResult = {}
test = {
"avatar": [],
"firstName": [],
"percent": [],
"lastName": []
}
for reader in readers:
test["percent"].append("value from another place")
test["firstName"].append(reader.firstName)
test["lastName"].append(reader.lastName)
test["avatar"].append(reader.avatar)
print("TEST: ", test)
readersResult[count] = test
count = count + 1
print("RESULT":, readersResult)
Examples can be found here.

Get max length of value inside a list which contains other lists

I got a list with keys and other lists. I want to create a function that checks the list for the longest value(string). It should give me back the longest string as number. I found nothing useful on the internet. only the strings with the key (value) need to be checked.
Output : It should count each character of the longest value(string).
Hope you can help me.
List:
[{'name': 'title', 'value': 'titel{TM} D3', 'is_on_label': 1},
{'name': 'DK in', 'value': '24V max 2.5A', 'is_on_label': 1,
'id_configuration': 79,
'options': [{'value': '30V max 3A', 'id_configuration_v': '1668'},
{'value': 'none', 'id_configuration_v': '1696'}]}]
function:
def checkLenFromConfigs(self, configs):
max_lenght = max(map(len, configs))
return max_lenght
You could recursively search for all values in your data structure:
data = [{
"name": "title",
"value": "titel{TM} D3",
"is_on_label": 1
},
[{
"name": "title",
"value": "titel{TM} D3",
"is_on_label": 1,
"sub_options": [
{
"value": "30V max 3A",
"id_configuration_v": "1668"
},
{
"value": "none none none none",
"id_configuration_v": "1696"
}
]
}],
{
"name": "DK in",
"value": "24V max 2.5A",
"is_on_label": 1,
"id_configuration": 79,
"options": [{
"value": "30V max 3A",
"id_configuration_v": "1668"
},
{
"value": "none",
"id_configuration_v": "1696"
}
]
}
]
def recur(data, count):
if isinstance(data, list):
for item in data:
count = recur(item, count)
elif isinstance(data, dict):
for k, v in data.items():
if k == 'value':
count.append(len(v))
else:
count = recur(v, count)
return count
result = recur(data, [])
print(max(result))
Out:
19

Swap values in dictionary which contain list of dictionaries?

I have dictionary which contain list of dictionaries as below.
I want to swap all values of list of dictionary based on name.
Example: swap_function('Arvind','Jayesh') should swap other values like surname, fullname & email.
I have already tried a lot from other website's references but not able achieve my goal.
data = {
"items":[
{
"name":"Arvind",
"surname":"Patel",
"fullname":"Arvind Patel",
"email":"abc#xyx.com"
},
{
"name":"Jayesh",
"surname":"Patel",
"fullname":"Jayesh Patel",
"email":"Patel#gmail.com"
},
{
"name":"Krishna",
"surname":"dave",
"fullname":"Krishna dave",
"email":"Krishna#xyz.com"
},
{
"name":"Aditya",
"surname":"Patel",
"fullname":"Aditya Patel",
"email":"Aditya#abc.com"
}
]
}
I have tried like below but after that I am out of ideas.
def name_swap(name1, name2):
for key, item in data.items():
first_dict = item[0]
second_dict = item[1]
third_dict = item[2]
forth_dict = item[3]
fifth_dict = item[4]
after name_swap('Arvind', 'Krishna')
output :
data = {
"items":[
{
"name":"Arvind",
"surname":"dave",
"fullname":"Krishna dave",
"email":"Krishna#xyz.com"
},
{
"name":"Jayesh",
"surname":"Patel",
"fullname":"Jayesh Patel",
"email":"Patel#gmail.com"
},
{
"name":"Krishna",
"surname":"Patel",
"fullname":"Arvind Patel",
"email":"abc#xyx.com"
},
{
"name":"Aditya",
"surname":"Patel",
"fullname":"Aditya Patel",
"email":"Aditya#abc.com"
}
]
}
Try this code:
i = next(i for i,item in enumerate(data['items']) if item['name'] == 'Arvind')
j = next(i for i,item in enumerate(data['items']) if item['name'] == 'Krishna')
data['items'][i]['name'], data['items'][j]['name'] = 'Krishna', 'Arvind'
And gives:
{'items': [{'name': 'Arvind',
'surname': 'dave',
'fullname': 'Krishna dave',
'email': 'Krishna#xyz.com'},
{'name': 'Jayesh',
'surname': 'Patel',
'fullname': 'Jayesh Patel',
'email': 'Patel#gmail.com'},
{'name': 'Krishna',
'surname': 'Patel',
'fullname': 'Arvind Patel',
'email': 'abc#xyx.com'},
{'name': 'Aditya',
'surname': 'Patel',
'fullname': 'Aditya Patel',
'email': 'Aditya#abc.com'}]}
Ok now let's generalize this example, with the following function:
def swap_dict_list(dict_list, val1, val2, target='name', block_target=True):
try:
i = next(i for i,item in enumerate(dict_list) if item[target] == val1)
j = next(i for i,item in enumerate(dict_list) if item[target] == val2)
except StopIteration:
return dict_list
dict_list[i], dict_list[j] = dict_list[j], dict_list[i]
if block_target:
dict_list[i][target], dict_list[j][target] = val1, val2
return dict_list
In your case, you will use the function in this:
data['items'] = swap_dict_list(data['items'], 'Arvind', 'Krishna', target='name', block_target=True)
And you will get the same result shown above.
Code explenation
The swap_dict_list function receives as input the list of dictionaries 'dict_list', the 2 values ​​to search ('val1' and 'val2') and the dictionary key on which to perform the target search.
The function finds the indexes corresponding to the two values ​​searched for, and if they both exist it performs the swap. If block_target is True, the target values ​​are not exchanged.
The search is effected efficiently using generator expression.
Try this :
def switch(list, name1, name2):
for item in list:
if item['name'] == name1:
item['name'] = name2
elif item['name'] == name1:
item['name'] = name2
return list
data = {
"items":[
{
"name":"Arvind",
"surname":"Patel",
"fullname":"Arvind Patel",
"email":"abc#xyx.com"
},
{
"name":"Jayesh",
"surname":"Patel",
"fullname":"Jayesh Patel",
"email":"Patel#gmail.com"
},
{
"name":"Krishna",
"surname":"dave",
"fullname":"Krishna dave",
"email":"Krishna#xyz.com"
},
{
"name":"Aditya",
"surname":"Patel",
"fullname":"Aditya Patel",
"email":"Aditya#abc.com"
}
]
}
data['items'] = switch(data['items'], 'Arvind', 'Jayesh')
print data
If i got you right:
First you want to find the indexes of the two dicts:
Find the index of a dict within a list, by matching the dict's value
then switch positions of the items:
How to switch position of two items in a Python list?
def switch(list,name1, name2):
index1 = next((index for (index, d) in enumerate(list) if d["name"] == name1), None)
index2 = next((index for (index, d) in enumerate(list) if d["name"] == name2), None)
list[index1]['name'], list[index2]['name'] = list[index2]['name'], list[index1]['name']
return list
data['items'] = switch(data['items'], 'Arvind', 'Krishna')

error list indices must be integers or slices, not str

Based on the title, help me solve the error.
i've tried to print the countryCode based on country_name which is in 'rv' variable.
country_found is list of data that have the same value on countries list,
and then i try to retrieve countryCode and there i got the error
rv = "Indonesia"
country_lower = rv.lower()
countries = {
"DATA": {
"data": [{
"countryId": "26",
"countryCode": "AU",
"name": "Australia"
}, {
"countryId": "17",
"countryCode": "ID",
"name": "Indonesia"
}]
}
}
def take_first(predicate, iterable):
for element in iterable:
if predicate(element):
yield element
break
country_found = list(
take_first(
lambda e: e['name'].lower() == country_lower,
countries['DATA']['data']
)
)
default_country_code = 'US'
country_code = (
country_found['countryCode']
if country_found
else default_country_code
)
print (country_code)
country_found is a list, but you are trying to get an item by a string index:
country_found['countryCode']
You've probably meant to get the first result of a match:
country_code = country_found[0]['countryCode'] if country_found else default_country_code
But, do you actually need to have the result as a list, what if you would just use next():
result = take_first(lambda e: e['name'].lower() == country_lower,
countries['DATA']['data'])
try:
country_code = next(result)['countryCode']
except StopIteration:
country_code = default_country_code
If I get your question correctly, below is what you might want to look into.
default_country_code = 'US'
print(country_found) # ==> list [{'countryId': '17', 'name': 'Indonesia', 'countryCode': 'IN'}]
print(country_found[0]) # ==> dictionary {'countryId': '17', 'name': 'Indonesia', 'countryCode': 'IN'}
print(country_found[0].get('countryCode',default_country_code)) # get countryCode. If countryCode is not there, get the default_country_code

Categories