defining multiple variables to an empty list in a loop - python

I am trying to create and assign 10 variables, only differenciated by their index, all as empty lists within a for loop.
The ideal output would be to have agent_1 = [], agent_2 = [], agent_n = []
I know I could write this all out but thought I should be able to create a simple loop. The main issue is assigning the empty list over each iteration
for i in range(1,10):
agent_ + i = []

Why don't you use dict object with keys equal to agent_i.
dic = {}
for i in range(1,10):
dic["agent_" + str(i)] = []
// access the dic directly and iterating purpose also just iterate through the dictionary.
print dic["agent_1"]
# iteration over the dictionary
for key,value in dic.items():
print key,value
Here is the link to code snippet

This is a horrible idea. I will let the code speak for itself:
n = 10
for i in range(n):
globals()['agent_%d' % (i + 1)] = []

a = {}
for i in xrange(10):
ab = "{}_{}".format("agent", i)
a[ab] = []
print a
#OP
{'agent_0': [], 'agent_1': [], 'agent_2': [], 'agent_3': [], 'agent_4': [], 'agent_5': [], 'agent_6': [], 'agent_7': [], 'agent_8': [], 'agent_9': []}

Related

Sort List into different lists

I have list with file_names in it.
(About 800 file_names)
[Example] file_name = 23475048_43241u_43x_pos11_7.npz
I need to sort the file_names and add it to lists. The file_names get sorted with the "pos". In my example is that pos11. (there are different pos -> pos0, pos12...)
I tried firstly to get all different pos_numbers in a Dict:
path =[filename for filename in glob.glob(os.path.join(my_dir, '*.npz'))]
posList = []
for file in path:
file_name = Path(file).parts[-1][:-4].split("_")
posList.append(file_name[3])
mylist = list(dict.fromkeys(posList))
files_dict = {}
for pos in mylist:files_dict[pos] = []
Output:
{'pos0': [], 'pos10': [], 'pos11': [], 'pos12': [], 'pos1': [], 'pos2': [], 'pos3': [], 'pos4': [], 'pos5': [], 'pos6': [], 'pos7': [], 'pos8': [], 'pos9': []}
And now I want to fill the different lists. But now I'm stuck. I want to to iter again over the list with file_names and add them to right list.
Not sure what your code is doing but you can use the below program which takes in list of file names and outputs a dictionary of sorted lists indexed by the pos which is what I think you are trying to do. (If not maybe edit your question to elaborate some more)
files = ['1_2_3_pos1_2.np', '2_3_1_pos2_2.npz']
files_dict = {}
for file in files:
pos = file.split('_')[3]
files_dict[pos] = files_dict.get(pos, []) + [file]
for k in files_dict.keys():
files_dict[k].sort()
print(files_dict)
Edit:
As #Stef suggested you can make it more effecient by using setdefault
files = ['1_2_3_pos1_2.np', '2_3_1_pos2_2.npz']
files_dict = {}
for file in files:
pos = file.split('_')[3]
files_dict.setdefault(pos, []).append(file)
for k in files_dict.keys():
files_dict[k].sort()
print(files_dict)
#ARandomDeveloper's answer clearly explains how to populate the dict by iterating through the list only once. I recommend to study their answer until you've understood it well.
This is a very common way to populate a dict. You will probably encounter this pattern again.
Because this operation of grouping into a dict is so common, module more_itertools offers a function map_reduce for exactly this purpose.
from more_itertools import map_reduce
posList = '''23475048_43241u_43x_pos11_7.npz
23475048_43241u_43x_pos1_7.npz
23475048_43241u_43x_pos10_7.npz
23475048_43241u_43x_pos8_7.npz
23475048_43241u_43x_pos22_7.npz
23475048_43241u_43x_pos2_7.npz'''.split("\n") # example list from uingtea's answer
d = map_reduce(posList, keyfunc=lambda f: f.split('_')[3])
print(d)
# defaultdict(None, {
# 'pos11': ['23475048_43241u_43x_pos11_7.npz'],
# 'pos1': ['23475048_43241u_43x_pos1_7.npz'],
# 'pos10': ['23475048_43241u_43x_pos10_7.npz'],
# 'pos8': ['23475048_43241u_43x_pos8_7.npz'],
# 'pos22': ['23475048_43241u_43x_pos22_7.npz'],
# 'pos2': ['23475048_43241u_43x_pos2_7.npz']
# })
Internally, map_reduce uses almost-exactly the same code as suggested in #ARandomDeveloper's answer, except with a defaultdict.
you need to extract the digits after pos use regex (\d+)_\d\.npz then use .sort() function
import re
posList = '''23475048_43241u_43x_pos11_7.npz
23475048_43241u_43x_pos1_7.npz
23475048_43241u_43x_pos10_7.npz
23475048_43241u_43x_pos8_7.npz
23475048_43241u_43x_pos22_7.npz
23475048_43241u_43x_pos2_7.npz'''.split("\n")
posList = sorted(posList, key=lambda x: int(re.search(r"(\d+)_\d\.npz", x)[1]))
print(posList)
results
['23475048_43241u_43x_pos1_7.npz',
'23475048_43241u_43x_pos2_7.npz',
'23475048_43241u_43x_pos8_7.npz',
'23475048_43241u_43x_pos10_7.npz',
'23475048_43241u_43x_pos11_7.npz',
'23475048_43241u_43x_pos22_7.npz'
]

recursive function that finds depth of empty list of lists

i need to write a recursive function that finds the depth of an empty list of lists, and it can only have one parameter, which is the list used. there is a test driver code for the problem which ill include below. i cant use advanced python stuff like isinstance or max and map because my professor wont allow it. i also am not sure what the make_list_structure function does exactly so if someone can explain what that was well that would be great.
import random
def make_list_structure(max_depth, p=.8):
if max_depth and random.random() < p:
new_list = []
for i in range(5):
sub_list = make_list_structure(max_depth - 1, p * .9)
if sub_list is not None:
new_list.append(sub_list)
return new_list
return None
if __name__ == '__main__':
print(how_deep([[[], [], [], [[[]]]], []]))
print(how_deep([]))
print(how_deep([[], []]))
print(how_deep([[[]], [], [[]], [[[]]]]))
print(how_deep([[[[], [[]], [[[]]], [[[[]]]]]]]))
print(how_deep([[[], []], [], [[], []]]))
Here's a short solution using max and map, and it's adaptation without it
def how_deep(values):
if not values:
return 1
sub_depth = 0
for value in values:
val_depth = how_deep(value)
if val_depth > sub_depth:
sub_depth = val_depth
return sub_depth + 1
def how_deep_nice(l):
if isinstance(l, list):
return 1 + max((how_deep_nice(item) for item in l), default=0)
return 0
print(how_deep([[[], [], [], [[[]]]], []])) # 5
print(how_deep([])) # 1
print(how_deep([[], []])) # 2

String matching and storing within a dictionary

I'm using pattern matching to collect the postcodes belonging to a street address and storing these addresses as values within a dictionary, here is what I have tried:
test = pd.DataFrame(['SR2', 'SA1', 'M16', 'KY6', 'SR6'], columns=(['postcode']))
street = pd.DataFrame(['UnnamedRoad,LlandeiloSA196UA,UK', '8NewRd,LlandeiloSA196DB,UK','1RomanRd,Banwen,NeathSA109LH,UK', 'UnnamedRoad,LlangadogSA199UN,UK', '48ColeAve,ChadwellStMary,GraysRM164JQ,UK', '37WellingtonRd,NorthWealdBassett,EppingCM166JY,UK'], columns=(['address']))
dictframe = {}
for i in test['postcode']:
dictframe[i] = list()
for k in range(0, len(test), 1):
dictframe[i].append(list(filter(lambda x: test['postcode'][k] in x, street['address'])))
However this prints all the outputs in each key, but I wanted only for where values appear to be within the key otherwise keep the list empty if nothing match. Here's the output I get:
{'SR2': [[],
['UnnamedRoad,LlandeiloSA196UA,UK',
'8NewRd,LlandeiloSA196DB,UK',
'1RomanRd,Banwen,NeathSA109LH,UK',
'UnnamedRoad,LlangadogSA199UN,UK'],
['48ColeAve,ChadwellStMary,GraysRM164JQ,UK',
'37WellingtonRd,NorthWealdBassett,EppingCM166JY,UK'],
[],
[]],
..
..
..
Expected output:
{'SR2': [],
'SA1': ['UnnamedRoad,LlandeiloSA196UA,UK',
'8NewRd,LlandeiloSA196DB,UK',
'1RomanRd,Banwen,NeathSA109LH,UK',
'UnnamedRoad,LlangadogSA199UN,UK']
...
...
}
corrected code - inner for loop is not required & in the string matching the index of test['postcode'] needs to be used, refer Python enumerate
import pandas as pd
test = pd.DataFrame(['SR2', 'SA1', 'M16', 'KY6', 'SR6'], columns=(['postcode']))
street = pd.DataFrame(['UnnamedRoad,LlandeiloSA196UA,UK', '8NewRd,LlandeiloSA196DB,UK','1RomanRd,Banwen,NeathSA109LH,UK', 'UnnamedRoad,LlangadogSA199UN,UK', '48ColeAve,ChadwellStMary,GraysRM164JQ,UK', '37WellingtonRd,NorthWealdBassett,EppingCM166JY,UK'], columns=(['address']))
dictframe = {}
for index, i in enumerate(test['postcode']):
dictframe[i] = list()
#for k in range(0, len(street), 1):
dictframe[i].append(list(filter(lambda x: test['postcode'][index] in x, street['address'])))
Output-
{'KY6': [[]],
'M16': [['48ColeAve,ChadwellStMary,GraysRM164JQ,UK',
'37WellingtonRd,NorthWealdBassett,EppingCM166JY,UK']],
'SA1': [['UnnamedRoad,LlandeiloSA196UA,UK',
'8NewRd,LlandeiloSA196DB,UK',
'1RomanRd,Banwen,NeathSA109LH,UK',
'UnnamedRoad,LlangadogSA199UN,UK']],
'SR2': [[]],
'SR6': [[]]}

Can Python set these variables at once?

I have these initializations:
countrys = []
codes = []
index_countrys = {}
index_codes = {}
I want to declare them at once like this:
countrys,codes = []
index_countrys,index_codes = {}
Is that allowed in Python?
You can use:
countries, codes = [], []
index_countries, index_codes = {}, {}
or even :
countries, codes, index_countries, index_codes = [], [], {}, {}
This is a good way to set multiple variables to distinct values using only a single line of code.
Searching “python set multiple variables site:stackoverflow.com” will give you many other options and recommendations on which ones to use.
countrys, code = [], []
index_countrys, index_codes = {}, {}
Yes, you can!
On python you can declare chained vars with equals sign.
Just like that:
countrys = codes = []
index_countrys = index_codes = {}

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)

Categories