I have 3 lists I created and I want to append them from the sql query output. I thought of created them as string as lst and append the output but I get the error below.
list_A1 = []
list_A2 = []
list_A3 = []
for i, name in enumerate(dataset['name'][1]['price']):
.
.
.
id_list = pd.read_sql_query(q, con=db)[price].tolist()
lst = f"{lst_name}_{id}"
#lst created the 3 list above.
lst.append(id_list).astype(int)
Error : AttributeError: 'str' object has no attribute 'append'
Edit:
What I mean is on each loop lst = list_A1..
and each of those lists gets populated with the data from the sql query
You can try follows,
list_A1 = []
list_A2 = []
list_A3 = []
for id_ in range(1,4,1):
lst = f"list_A1"
vars()[lst].append(id_)
print(list_A1)
Output
[1, 2, 3]
Reference
How do I create variable variables?
You can't create variable using string f"{lst_name}_{id}". You may only use it as key in dictionary all_lists[f"{lst_name}_{id}"] = []. And you should use dictionary
all_lists = {
"list_A1": [],
"list_A2": [],
"list_A3": [],
}
for ... in ...:
id_list = ....astype(int).tolist()
key = f"{lst_name}_{id}"
lst = all_lists[key]
lst.append( id_list )
You could do it even dinamically
all_lists = {} # empty dictionary
for ... in ...:
id_list = ....astype(int).tolist()
key = f"{lst_name}_{id}"
# create list if not exists yet
if key not in all_lists:
all_lists[key] = []
lst = all_lists[key]
lst.append( id_list )
BTW: You can create variable with vars() or similar functions but it is not preferred. You have dictionary for this.
Related
I have multiple sets of two lists that I need to convert into one dictionary by looking at every permutation across rows in a dataframe.
For example, if there is a list of ['cat1','cat2'] and a list of ['top1','top2'], I'd like a resulting dictionary of {'cat1':'top1','cat1':'top2','cat2':'top1','cat2':'top2'}
Here is my current code that gets close but ends up using every letter and not string...
import pandas as pd
test_df = pd.DataFrame()
test_df['category'] = [['cat1'],['cat2'],['cat3','cat3.5'],['cat5']]
test_df['topic'] = [['top1'],[''],['top2','top3'],['top4']]
final_dict = {}
res = {}
for index, row in test_df.iterrows():
print(row["category"], row["topic"])
temp_keys = row["category"]
temp_values = row["topic"]
res = {}
for test_key in temp_keys:
#print(test_key)
for test_value in temp_values:
#print(test_value)
#print(res)
test_key = str(test_key)
print(test_key)
test_value = str(test_value)
print(test_value)
#res[key] = key
#res = dict(zip(str(key),str(test_value)))
res = dict(zip(str(test_key),str(test_value)))
print(res)
print('\n')
If you want a list of tuple instead of dict, you can use pd.MultiIndex.from_product:
out = test_df.apply(pd.MultiIndex.from_product, axis=1).apply(list)
>>> out
0 [(cat1, top1)]
1 [(cat2, )]
2 [(cat3, top2), (cat3, top3), (cat3.5, top2), (...
3 [(cat5, top4)]
dtype: object
>>> out.tolist()
[[('cat1', 'top1')],
[('cat2', '')],
[('cat3', 'top2'), ('cat3', 'top3'), ('cat3.5', 'top2'), ('cat3.5', 'top3')],
[('cat5', 'top4')]]
i would like to know how I could create a dictionary using the three lists. coun_keys to be a key and months_values and cases_values are to be the values.
I only found sources where I could use the zip() function to have a key: value, but how can I have key: value1, value2?
def main(csvfile,country ,type ):
with open(csvfile,"r") as file:
if type.lower() == "statistics ":
coun_keys = []
months_values = []
cases_values = []
listname =[]
coun_month={}
for line in file:
columns = (line.strip().split(","))
listname.append(columns)
listname.pop(0)
for line in listname:
date1 = line[3].split("/")
coun_keys.append(str(line[2]))
months_values.append(int(date1[1]))
cases_values.append(int(line[4]))
Do you mean, like:
list1 = [1, 2, 3]
list2 = 'abc'
list3 = [5, 6, 7]
print(dict(zip(list1,zip(list2, list3))))
#############################
For your code specifically, I would break up what you want to do into pieces. First define what you want to do with each line of your file:
def process_line(line):
line = line.strip().split(',')
date1 = line[3].split("/")
key = str(line[2])
month = int(date1[1])
case = int(line[4])
return key,(month,case)
Notice I group the values I want in a tuple, in particular, I want the process_line function to return my "key" and my "value" (a pair). Now open your file and process the lines:
f = open(csvfile)
next(f) #Skip the first line
result = dict(process_line(line) for line in f)
f.close()
This might help...
newDict = dict(zip(coun_keys, [months_values, cases_values]))
Assuming they're the same length, you can also do:
your_dict = {coun_keys[i] : (months_values[i], cases_values[i]) for i in range(len(coun_keys))}
For example,
lst1 = [a,b,c,d]
lst2 = [1,2,3,4]
lst3 = [5,6,7,8]
dict1 = dict(zip(lst1,zip(lst2,lst3)))
I'm trying to merge data from 2 lists by an ID:
list_a = [
(u'65d92438497c', u'compute-0'),
(u'051df48db621', u'compute-4'),
(u'd6160db0cbcd', u'compute-3'),
(u'23fc20b59bd6', u'compute-1'),
(u'0db2e733520d', u'controller-1'),
(u'89334dac8a59', u'compute-2'),
(u'51cf9d50b02e', u'compute-5'),
(u'f4fe106eaeab', u'controller-2'),
(u'06cc124662dc', u'controller-0')
]
list_b = [
(u'65d92438497c', u'p06619'),
(u'051df48db621', u'p06618'),
(u'd6160db0cbcd', u'p06620'),
(u'23fc20b59bd6', u'p06622'),
(u'0db2e733520d', u'p06612'),
(u'89334dac8a59', u'p06621'),
(u'51cf9d50b02e', u'p06623'),
(u'f4fe106eaeab', u'p06611'),
(u'06cc124662dc', u'p06613')
]
list_ab = [
(u'65d92438497c', u'p06619', u'compute-0'),
(u'051df48db621', u'p06618', u'compute-4'),
(u'd6160db0cbcd', u'p06620', u'compute-3'),
(u'23fc20b59bd6', u'p06622', u'compute-1'),
(u'0db2e733520d', u'p06612', u'controller-1'),
(u'89334dac8a59', u'p06621', u'compute-2'),
(u'51cf9d50b02e', u'p06623', u'compute-5'),
(u'f4fe106eaeab', u'p06611', u'controller-2'),
(u'06cc124662dc', u'p06613', u'controller-0')
]
You can see that the first field in an ID, identical between list_a and list_b and I need to merge on this value
I'm not sure what type of data I need for result_ab
The purpose of this is to find 'compute-0' from 'p06619' so maybe there is a better way than merge.
You are using a one-dimensional list containing a tuple, it could be not needed. Anyway, to obtain the output you require:
list_a = [(u'65d92438497c', u'compute-0')]
list_b = [(u'65d92438497c', u'p-06619')]
result_ab = None
if list_a[0][0] == list_b[0][0]:
result_ab = [tuple(list(list_a[0]) + list(list_b[0][1:]))]
Here is my solution :
merge = []
for i in range(0,len(list_a)):
if list_a[i][0] == list_b[i][0]:
merge.append([tuple(list(list_a[i]) + list(list_b[i][1:]))])
The idea is to create a dictionary with the keys as the first element of both the lists and values as the list object with all the elements matching that key.
Next, just iterate over the dictionary and create the required new list object:
from collections import defaultdict
res = defaultdict(list)
for elt in list_a:
res[elt[0]].extend([el for el in elt[1:]])
for elt in list_b:
res[elt[0]].extend([el for el in elt[1:]])
list_ab = []
for key, value in res.items():
elt = tuple([key, *[val for val in value]])
list_ab.append(elt)
print(list_ab)
I am really new to Python and I am having a issue figuring out the problem below.
I have a list like:
my_list = ['testOne:100', 'testTwo:88', 'testThree:76', 'testOne:78', 'testTwo:88', 'testOne:73', 'testTwo:66', 'testThree:90']
And I want to group the elements based on the occurrence of elements that start with 'testOne'.
Expected Result:
new_list=[['testOne:100', 'testTwo:88', 'testThree:76'], ['testOne:78', 'testTwo:88'], ['testOne:73', 'testTwo:66', 'testThree:90']]
Just start a new list at every testOne.
>>> new_list = []
>>> for item in my_list:
if item.startswith('testOne:'):
new_list.append([])
new_list[-1].append(item)
>>> new_list
[['testOne:100', 'testTwo:88', 'testThree:76'], ['testOne:78', 'testTwo:88'], ['testOne:73', 'testTwo:66', 'testThree:90']]
Not a cool one-liner, but this works also with more general labels:
result = [[]]
seen = set()
for entry in my_list:
test, val = entry.split(":")
if test in seen:
result.append([entry])
seen = {test}
else:
result[-1].append(entry)
seen.add(test)
Here, we are keeping track of the test labels we've already seen in a set and starting a new list whenever we encounter a label we've already seen in the same list.
Alternatively, assuming the lists always start with testOne, you could just start a new list whenever the label is testOne:
result = []
for entry in my_list:
test, val = entry.split(":")
if test == "testOne":
result.append([entry])
else:
result[-1].append(entry)
It'd be nice to have an easy one liner, but I think it'd end up looking a bit too complicated if I tried that. Here's what I came up with:
# Create a list of the starting indices:
ind = [i for i, e in enumerate(my_list) if e.split(':')[0] == 'testOne']
# Create a list of slices using pairs of indices:
new_list = [my_list[i:j] for (i, j) in zip(ind, ind[1:] + [None])]
Not very sophisticated but it works:
my_list = ['testOne:100', 'testTwo:88', 'testThree:76', 'testOne:78', 'testTwo:88', 'testOne:73', 'testTwo:66', 'testThree:90']
splitting_word = 'testOne'
new_list = list()
partial_list = list()
for item in my_list:
if item.startswith(splitting_word) and partial_list:
new_list.append(partial_list)
partial_list = list()
partial_list.append(item)
new_list.append(partial_list)
joining the list into a string with delimiter |
step1="|".join(my_list)
splitting the listing based on 'testOne'
step2=step1.split("testOne")
appending "testOne" to the list elements to get the result
new_list=[[i for i in str('testOne'+i).split("|") if len(i)>0] for i in step2[1:]]
My code
class getCol:
matrix = []
def __init__(self, file, delim=" "):
with open(file, 'rU') as f:
getCol.matrix = [filter(None, l.split(delim)) for l in f]
def __getitem__ (self, key):
column = []
for row in getCol.matrix:
try:
column.append(row[key])
except IndexError:
# pass
column.append("")
return column
list1 = getCol('/home/milenko/EDIs/site1/newst2.txt')[0]
list2 = getCol('/home/milenko/EDIs/site2/newst2.txt')[0]
list3 = getCol('/home/milenko/EDIs/site3/newst2.txt')[0]
list4 = getCol('/home/milenko/EDIs/site4/newst2.txt')[0]
list5 = getCol('/home/milenko/EDIs/site5/newst2.txt')[0]
list6 = getCol('/home/milenko/EDIs/site6/newst2.txt')[0]
list7 = getCol('/home/milenko/EDIs/site7/newst2.txt')[0]
list8 = getCol('/home/milenko/EDIs/site8/newst2.txt')[0]
list9 = getCol('/home/milenko/EDIs/site9/newst2.txt')[0]
list10 = getCol('/home/milenko/EDIs/site10/newst2.txt')[0]
list11 = getCol('/home/milenko/EDIs/site11/newst2.txt')[0]
list12 = getCol('/home/milenko/EDIs/site12/newst2.txt')[0]
list13 = getCol('/home/milenko/EDIs/site13/newst2.txt')[0]
list14 = getCol('/home/milenko/EDIs/site14/newst2.txt')[0]
list15 = getCol('/home/milenko/EDIs/site15/newst2.txt')[0]
list_of_lists = []
list_of_lists.append(list1)
list_of_lists.append(list2)
list_of_lists.append(list3)
list_of_lists.append(list4)
list_of_lists.append(list5)
list_of_lists.append(list6)
list_of_lists.append(list7)
list_of_lists.append(list8)
list_of_lists.append(list9)
list_of_lists.append(list10)
list_of_lists.append(list11)
list_of_lists.append(list12)
list_of_lists.append(list13)
list_of_lists.append(list14)
list_of_lists.append(list15)
result = []
# Loop the inner lists from list_of_lists, this will be list1, list2, list3...
for inner_list in list_of_lists:
# Loop each element of the inner lists
for element in inner_list:
# Make sure the element is not already in the result (this can also be done with sets)
if element not in result:
# Add the inner element to result
result.append(element)
# Sort the result
result = sorted(result)
print("\n".join(map(str, result)))
But problem is here
1.92413
10.15704
1026.00000
10260.00000
10672.43359
11.81549
1104.06055
114.21478
12.00000
12415.04102
1284.33289
13.74474
132.00000
132.86391
1376.00000
13760.00000
14442.18457
1494.04028
15.00000
I just want normal ordering from smallest to largest.How should I solve this?Is there any other alternative to sort?
It's sorting as strings. To sort as numbers, use the key argument:
result = sorted(result, key=float)
This converts each string to a float for sorting purposes, but leaves the
data as is.
Since you're assigning the result to the same identifier, you can also:
result.sort(key=float)
You need to convert the values in your list from strings to a numeric type like floats.