Creating python dictionaries using for loop - python

I make a bunch of matrices that I want to store in python dictionaries and I always find myself typing the same thing for every state that I want to build, i.e.
Ne21_1st_state = {}
Ne21_2nd_state = {}
Ne21_3rd_state = {}
Ne21_4th_state = {}
Ne21_5th_state = {}
Ne21_6th_state = {}
...
Ne21_29th_state = {}
Ne21_30th_state = {}
Can somebody help me automate this using python for loops?
Thanks in advance!
I want something like this:
for i in range(3, 11):
states = f'Ar36_{i}th_state'
print(states)
where the output would be:
Ar36_3th_state
Ar36_4th_state
Ar36_5th_state
Ar36_6th_state
Ar36_7th_state
Ar36_8th_state
Ar36_9th_state
Ar36_10th_state
but instead of printing it it would create individual dictionaries named Ar36_3th_state, Ar36_4th_state, Ar36_5th_state, ...

can't we make a List of dictionaries
List of 30 (or any N) elements where each element is a dictionary with key = "Ar36_{i}th_state" and value = {whatever value you want}

You can create "name" of pseudo variable and use it as key in dictionary like:
my_dic = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}
my_empty_dic = {}
solution = {}
for i in range(1, 31):
name = 'Ne21_'+str(i)+'st_state'
#solution[name] = my_dic
solution[name] = my_empty_dic
for pseudo_variable in solution:
print(pseudo_variable, solution[pseudo_variable])
print(solution['Ne21_16st_state'])
for pseudo_variable in solution:
if '_16st' in pseudo_variable:
print(pseudo_variable, solution[pseudo_variable])

One way I've done this is using list comprehension.
key = list(
str(input(f"Please enter a Key for value {x + 1}: "))
if x == 0
else str(input(f"\nPlease enter a Key for value {x + 1}: "))
for x in range(3))
value = list(str(input(f"\nPlease enter a Bool for value {x + 1}: "))
for x in range(3))
BoolValues = dict(zip(key, value))
I first create a list of keys followed by a list of the values to be stored in the keys. Then I just zip them together into a dictionary. The conditional statements in the first list are only for a slightly better user-experience with \n being added if it's passed the first input.
Actually now that I look back on the question it may be slightly different to what I was thinking, are you trying to create new dictionaries for every matrix? If that is the case, is it something similar to this?: How do you create different variable names while in a loop?

Related

How to check a list for duplicates and add values if there are any?

I'm totally beginner with coding and just need help with some stuff.
My dream was to write a smart shopping list that automatically detects duplicates and increases the weight of duplicate products.
I get the shopping list from an external file which has the following form:
weight\n
ingredient\n
eg.
60
eggs
120
beef meat
25
pasta
120
eggs
etc...
After converting this files to dictionaries by this code:
final_list = []
def get_list(day_list):
for day in range(len(day_list)):
day += 1
day_to_open = f'Days/day{str(day)}.txt'
with open(day_to_open, 'r') as file:
day1 = file.readlines()
day1 = [item.rstrip() for item in day1]
x = 0
y = 1
list = []
for item in range(0, len(day1), 2):
dictio = {day1[y]: day1[x]}
x += 2
y += 2
list.append(dictio)
final_list.append(list)
list = []
for item in final_list:
list += item
return list
days = [1, 2, 3]
list = get_list(day_list=days)
Finally I get list of dictionaries like that:
[{'eggs': '60'}, {'beef meat': '120'}, {'pasta': '25'}, {'eggs': '120'}]
How can I iterate through the dictionary to check if any products are repeating, and if so leave one with the added weight?
For three weeks I have been trying to solve it, unfortunately to no avail.
Thank you very much for all your help!
#Edit
my goal is to make it look like this:
[{'eggs': 180}, {'beef meat': 120}, {'pasta': 25}]
#egg weight added (120 + 60)#
lis = [{'eggs': '60'}, {'beef meat': '120'}, {'pasta': '25'}, {'eggs': '120'}]
# make 1 dict from list of dicts and update max value
new = {}
for d in lis:
for k, v in d.items():
if (k not in new) or (int(v) > int(new[k])):
new[k] = v
# rebuild list of dicts
lis = [{k:v} for k, v in new.items()]
print(lis)
# [{'eggs': '120'}, {'beef meat': '120'}, {'pasta': '25'}]
As ShadowRanger has pointed out, it's not common practice to have a list of multiple dictionaries as you have done. Dictionaries are very useful if used correctly.
I'm not entirely sure the structure of the files you are reading, so I will just explain a way forward and leave it up to you to implement it. What I would suggest is that you first initiate a dictionary with all the necessary keys (ingredients in your case) with each of the values set to 0 (as an integer or float, rather than a string), so you would get a dictionary like this:
shopping_list = {'eggs': 0, 'beef meat': 0, 'pasta': 0}
Then, you will be able to access each of the values by calling the shopping_list dictionary and specifying the key of interest. For example, if you wanted to print the value of eggs, you would write:
print(shopping_list['eggs']) # this would return 0
You can then easily increase/decrease a value of interest; for example, to add 10 to pasta, you would write:
shopping_list['eggs'] += 10
Using this method, you can then iterate through each of your items, select the ingredient of interest and add the weight. So if you have duplicates, it will just add to the same ingredient. Again, I'm not sure the structure of the files you are reading, but it would be something along the lines of:
for ingredient, weight in file:
shopping_list[ingredient] += weight
Good luck for your dream - all the best!

Numbered list of items in a for loop

My python skills are rusty on this one.
I have a list of items. I want to create an id for them and build a dictionary.
example:
users = ["John","Peter","Alice"]
I want to create an outcome like
users_dict = {"u1":"John","u2":"Peter","u3":"Alice"}
I am having trouble figuring out how to create a for loop that will dynamically create u + integer. I may be dealing with a large qty of items in the list.
Any guidance would be appreciated.
You can use a dictionary comprehension with a formatted string as the keys:
>>> {f"u{i}": user for i, user in enumerate(users, start=1)}
{'u1': 'John', 'u2': 'Peter', 'u3': 'Alice'}
This goes through your users, creates the key u* for each user where * is the position in the original list (starting from 1 as per your desired output), and assigns it the user name
You can try this:
users = ["John","Peter","Alice"]
newusers = {}
for x in range(len(users)):
newusers['u' + str(x+1)] = users[x]
newusers
# {'u1': 'John', 'u2': 'Peter', 'u3': 'Alice'}
You can open Jupyter notebook and play (minimal attention to documentation required).
You start with your list
users = ["John","Peter","Alice"]
Then you need size of the list
len(users)
Now, you need list of all integers from 1 to the size. You can get it with range:
range(len(users))
So to get a list of all integers starting 1, you do:
list(range(1, len(users) + 1))
But for the future processing, you may prefer this form:
[i + 1 for i in range(len(users))]
because you can easily add prefix:
['u'+str(i + 1) for i in range(len(users))]
Now you combine two lists:
zip(['u'+str(i + 1) for i in range(len(users))], users)
and enjoy your dictionary:
dict(zip(['u'+str(i + 1) for i in range(len(users))], users))
It is pretty simple
# initializing lists
test_values = ["John","Peter","Alice"]
hint = "u"
using naive method
to convert lists to dictionary
res = {}
for index, value in enumerate(test_values):
res[hint+str(index+1)] = value
del test_values # memory efficient
Printing resultant dictionary
print ("Resultant dictionary is : " + str(res))
Then answer is like
{"u1":"John","u2":Peter","u3":"Alice"}

Find if value exists in multiple list and get names of it

I found similar question, but I'm not able to convert answer to match my needs.
(Find if value exists in multiple lists)
So, basicly, I have multiple lists, and I want to list all of them, which contain current user username.
import getpass
value = getpass.getuser()
rep_WOHTEL = ['user1','user2','user3']
rep_REPDAY = ['user4','user1','user3']
rep_ZARKGL = ['user3','user1','user2']
rep_WOHOPL = ['user3','user2','user5']
#No idea how code below works
w = next(n for n,v in filter(lambda t: isinstance(t[1],list) and t[0].startswith('rep_'), globals().items()) if value in v)
print(w)
If current user is user1, I want it to print rep_WOHTEL, rep_REPDAY and rep_ZARKGL. Code above print only ony of them.
How should I change this part of script, to print all I want?
Like I commented in the linked question, iterating through all of globals() or locals() is a bad idea. Store your lists together in a single dictionary or list, and iterate through that instead.
value = "user1"
named_lists = {
"WOHTEL": ['user1','user2','user3'],
"REPDAY": ['user4','user1','user3'],
"ZARKGL": ['user3','user1','user2'],
"WOHOPL": ['user3','user2','user5']
}
names = [name for name, seq in named_lists.items() if value in seq]
print(names)
Result:
['REPDAY', 'ZARKGL', 'WOHTEL']
Checking if value is in all global lists, and if true, print which list(s) contains the required value.
Code:
rep_WOHTEL = ['user1','user2','user3']
rep_REPDAY = ['user4','user1','user3']
rep_ZARKGL = ['user3','user1','user2']
rep_WOHOPL = ['user3','user2','user5']
value = 'user1'
x = globals().items()
for n,v in filter(lambda t: isinstance(t[1],list) and t[0].startswith('rep_'), x):
if value in v:
print(n)
Output:
rep_REPDAY
rep_ZARKGL
rep_WOHTEL
More info about the used functions:
globals()
dict.items()
filter()
isinstance()
startswith()

Create a list dynamically and store all the values matching with current value in python 3.x

I have a text file which has data created dynamically like
1000L 00V
2000L -10V
3500L -15V
1250L -05V
1000L -05V
2000L -05V
6000L -10V
1010L 00V
and so on...
The numbers before V could vary from -160 to +160
I want to create a list (not using dictionary) dynamically and store the values in a list according to the matching numbers before V
In this case I want to create sets of list as follows
00 = ["1000", "1010"]
-10 = ["2000", "6000"]
-15 = ["3500"]
-05 = ["1250", "1000", "2000"]
Tried code:
if name.split()[1] != "":
gain_value = name.split()[1]
gain_value = int(gain_value.replace("V", ""))
if gain_value not in gain_list:
gain_list.append(gain_value)
gain_length = len(gain_list)
print(gain_length)
g['gain_{0}'.format(gain_length)] = []
'gain_{0}'.format(gain_length).append(L_value)
else:
index_value = gain_list.index(gain_value)
g[index_value].append(L_value)
for x in range(0, len(gain_list)):
print(str(gain_list[x]) + "=" + 'gain_{0}'.format(x))
But the above code doesn't work as I get an error while appending 'gain_{0}'.format(gain_length).append(L_value) and I am unsure how to print the list dynamically after its created as mentioned in my required output.
I can't use dictionary for the above method because I want to give the lists dynamically as input to pygal module as below:
as I need the output for pygal module as input like :
for x in range(0, gain_length):
bar_chart.x_labels = k_list
bar_chart.add(str(gain_length[x]),'gain_{0}'.format(x))
Here I can add the values only from a list not from a dictionary
you can use collections.defaultdict:
import collections
my_dict = collection.defaultdict(list)
with open('your_file') as f:
for x in f:
x = x.strip().split()
my_dict[x[1][:-1]].append(x[0])
output:
defaultdict(<type 'list'>, { '00': ["1000", "1010"],
'-10':["2000", "6000"],
'-15': ["3500"],
'-05': ["1250", "1000", "2000"]})
for your desired output:
for x,y in my_dict.items():
print "{} = {}".format(x,y)

Append several variables to a list in Python

I want to append several variables to a list. The number of variables varies. All variables start with "volume". I was thinking maybe a wildcard or something would do it. But I couldn't find anything like this. Any ideas how to solve this? Note in this example it is three variables, but it could also be five or six or anything.
volumeA = 100
volumeB = 20
volumeC = 10
vol = []
vol.append(volume*)
You can use extend to append any iterable to a list:
vol.extend((volumeA, volumeB, volumeC))
Depending on the prefix of your variable names has a bad code smell to me, but you can do it. (The order in which values are appended is undefined.)
vol.extend(value for name, value in locals().items() if name.startswith('volume'))
If order is important (IMHO, still smells wrong):
vol.extend(value for name, value in sorted(locals().items(), key=lambda item: item[0]) if name.startswith('volume'))
Although you can do
vol = []
vol += [val for name, val in globals().items() if name.startswith('volume')]
# replace globals() with locals() if this is in a function
a much better approach would be to use a dictionary instead of similarly-named variables:
volume = {
'A': 100,
'B': 20,
'C': 10
}
vol = []
vol += volume.values()
Note that in the latter case the order of items is unspecified, that is you can get [100,10,20] or [10,20,100]. To add items in an order of keys, use:
vol += [volume[key] for key in sorted(volume)]
EDIT removed filter from list comprehension as it was highlighted that it was an appalling idea.
I've changed it so it's not too similar too all the other answers.
volumeA = 100
volumeB = 20
volumeC = 10
lst = map(lambda x : x[1], filter(lambda x : x[0].startswith('volume'), globals().items()))
print lst
Output
[100, 10, 20]
do you want to add the variables' names as well as their values?
output=[]
output.append([(k,v) for k,v in globals().items() if k.startswith('volume')])
or just the values:
output.append([v for k,v in globals().items() if k.startswith('volume')])
if I get the question appropriately, you are trying to append different values in different variables into a list. Let's see the example below.
Assuming :
email = 'example#gmail.com'
pwd='Mypwd'
list = []
list.append(email)
list.append (pwd)
for row in list:
print(row)
# the output is :
#example#gmail.com
#Mypwd
Hope this helps, thank you.

Categories