Related
This is a nested list:
matrix = [['0', '0', '0', '0', '0', '1', '1', '0', '0', '0'],
['0', '1', '1', '1', '1', '1', '0', '0', '0', '0'],
['0', '0', '1', '1', '0', '1', '0', '1', '1', '0'],
['0', '1', '0', '0', '0', '0', '1', '0', '0', '1'],
['0', '0', '0', '1', '0', '0', '1', '0', '1', '0'],
['0', '0', '0', '0', '1', '0', '1', '1', '1', '0'],
['0', '1', '1', '1', '1', '0', '1', '1', '1', '1'],
['1', '1', '1', '1', '1', '1', '1', '1', '1', '1']]
#output should be [1,2,2,2,3,1,5,3,4,2]
Height = 8
Width = 10
I want to know how I can get the height of each column. And then each height, I want to put it in a list.
We counting 1's and they only count for the height if they are adjoint 1's.
We start with counting below and then go up.
Output should be [1,2,2,2,3,1,5,3,4,1]
I only want to use build in Python functions.
I tried with a for loop and if, else statements.
For loop iterate through the list.
like if i == '1' add 1 to counter.
if i == '0' reset counter and add the last value from counter to counter1, but only if counter is greater then counter1.
You can use itertools.takewhile on the reversed, zipped matrix:
from itertools import takewhile
out = [len(list(takewhile(lambda x: x=='1', reversed(l)))) for l in zip(*matrix)]
output:
[1, 2, 2, 2, 3, 1, 5, 3, 4, 2]
If you don't want to import takewhile, use the recipe:
def takewhile(predicate, iterable):
# takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
for x in iterable:
if predicate(x):
yield x
else:
break
How it works:
zip rotates the matrix:
>>> list(zip(*matrix))
[('0', '0', '0', '0', '0', '0', '0', '1'),
('0', '1', '0', '1', '0', '0', '1', '1'),
('0', '1', '1', '0', '0', '0', '1', '1'),
('0', '1', '1', '0', '1', '0', '1', '1'),
('0', '1', '0', '0', '0', '1', '1', '1'),
('1', '1', '1', '0', '0', '0', '0', '1'),
('1', '0', '0', '1', '1', '1', '1', '1'),
('0', '0', '1', '0', '0', '1', '1', '1'),
('0', '0', '1', '0', '1', '1', '1', '1'),
('0', '0', '0', '1', '0', '0', '1', '1')]
The list comprehension with reversed rotates the other way around (actually inverses each row):
>>> [list(reversed(l)) for l in zip(*matrix)]
[['1', '0', '0', '0', '0', '0', '0', '0'],
['1', '1', '0', '0', '1', '0', '1', '0'],
['1', '1', '0', '0', '0', '1', '1', '0'],
['1', '1', '0', '1', '0', '1', '1', '0'],
['1', '1', '1', '0', '0', '0', '1', '0'],
['1', '0', '0', '0', '0', '1', '1', '1'],
['1', '1', '1', '1', '1', '0', '0', '1'],
['1', '1', '1', '0', '0', '1', '0', '0'],
['1', '1', '1', '1', '0', '1', '0', '0'],
['1', '1', '0', '0', '1', '0', '0', '0']]
takewhile keepd the elements while the condition is True, here while the items are '1' (lambda x: x=='1'), and len gets the length of the output:
>>> l = ['1', '1', '1', '0', '0', '0', '1', '0']
>>> list(takewhile(lambda x: x=='1', l))
['1', '1', '1']
>>> len(list(takewhile(lambda x: x=='1', l)))
3
NB. functions like zip, reversed, takewhile are generators, they don't produce output unless something consumes it, that's why I used list(generator(…)) in the exammples
solution with classical python loops:
out = []
for l in zip(*matrix):
counter = 0
for elem in reversed(l):
if elem == '1':
counter +=1
else:
break
out.append(counter)
titleValues = {'Movie 1 (1998)': ['0', '1', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'], 'Movie 2 (1994)': ['0', '1', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '1', '1', '0', '0']}
categories={'unknown': '0', 'Action': '1', 'Adventure': '2', 'Animation': '3', "Children's": '4', 'Comedy': '5', 'Crime': '6', 'Documentary': '7', 'Drama': '8', 'Fantasy': '9', 'Film-Noir': '10', 'Horror': '11', 'Musical': '12', 'Mystery': '13', 'Romance': '14', 'Sci-Fi': '15', 'Thriller': '16', 'War': '17', 'Western': '18'}
selectedCol = 1
titles=[]
for key, value in titleValues.items():
for num in value:
if num == '1':
valIdx = value.index(num)
if valIdx == selectedCol:
titles.append(key)
else:
continue
print(titles)
output:
['Movie 1 (1998)', 'Movie 1 (1998)', 'Movie 2 (1994)', 'Movie 2 (1994)', 'Movie 2 (1994)', 'Movie 2 (1994)']
I think it appears 6 times because of the six '1' occurrences. However, how can I only obtain two names as for both lists '1' appears at index 1.
['Movie 1 (1998)', 'Movie 2 (1994)']
only when titleValues contains a one, put key once in a list:
titles = [k for k,v in zip(titleValues.keys(),titleValues.values()) if '1' in v]
result will be
print(titles)
# ['Movie 1 (1998)', 'Movie 2 (1994)']
Explanation
Create two iterables (keys, values)
print(titleValues.keys())
#dict_keys(['Movie 1 (1998)', 'Movie 2 (1994)'])
print(titleValues.values())
#dict_values([['0', '1', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'], ['0', '1', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '1', '1', '0', '0']])
zip, is a function to iterate element-wise and simultanouesly over two iterables
print(list(zip(titleValues.keys(),titleValues.values())))
# [('Movie 1 (1998)', ['0', '1', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0']), ('Movie 2 (1994)', ['0', '1', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '1', '1', '0', '0'])]
in a for-comprehension you can access elements of both iterables (specified variable name: k for element in first iterable and v for element in second)
I think I understand what need to be done. However I can't get the results right. I have a list of lists with several items. I want to create a new list(with more elements, based on a criteria) but keeping length of the original list of lists. Let's exemplify:
test = [[2, 3, 5, 6, 9, 10, 11, 13, 14, 16, 18, 20, 23, 24, 25], [1, 4, 5, 6, 7, 9, 11, 12, 13, 15, 16, 19, 20, 23, 24]] # there are hundreds of lists in the original list
list_num_sor = []
new_list = []
for row in test:
for i in range(1, 26):
if i in row:
new_list.append('1')
else:
new_list.append('0')
list_num_sor.append(new_list)
What I'm trying to do is, for each list in test, I want to validate if in a range 1-25, this number is in the list, returning 1, otherwise, 0. The original list has 15 elements, the new one should have 25.
The result should be:
list_num_sor = [['0', '1', '1', '0', '1', '1', '0', '0', '1', '1', '1', '0', '1', '1', '0', '1', '0', '1', '0', '1', '0', '0', '1', '1', '1'],
['1', '0', '0', '1', '1', '1', '1', '0', '1', '0', '1', '1', '1', '0', '1', '1', '0', '0', '1', '1', '0', '0', '1', '1', '0']]
But what I'm getting is a list of lists, where each element has the results of all the items from the first list of list:
[['0', '1', '1', '0', '1', '1', '0', '0', '1', '1', '1', '0', '1', '1', '0', '1', '0', '1', '0', '1', '0', '0', '1', '1', '1', '1', '0', '0', '1', '1', '1', '1', '0', '1', '0', '1', '1', '1', '0', '1', '1', '0', '0', '1', '1', '0', '0', '1', '1', '0'],
['0', '1', '1', '0', '1', '1', '0', '0', '1', '1', '1', '0', '1', '1', '0', '1', '0', '1', '0', '1', '0', '0', '1', '1', '1', '1', '0', '0', '1', '1', '1', '1', '0', '1', '0', '1', '1', '1', '0', '1', '1', '0', '0', '1', '1', '0', '0', '1', '1', '0']]
Hope I could make it understandable. I need it to be a list of lists to create a DF afterwards. I don't think processing time would be a problem as it is not something big enough for it to become a problem.
Hope you people could help me out.
Thanks
So you want a new list for every row in your old list:
for row in test:
new_list.append([])
for i in range(1, 26):
if i in row:
new_list[-1].append('1')
else:
new_list[-1].append('0')
Every iteration add a list to your list of lists, and then append the 0/1 values to the last list added ([-1]). More concisely:
new_list = [[1 if i in row else 0 for i in range(1, 26)] for row in test]
This has the added benefit you can just put it in your call to the DataFrame constructor directly.
Can we perform replace on python list?
I have that list that is imported from csv file:
[['1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'], ['2', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0'], ['3', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0']]
fist index(mark as bold) from list above will became costumer id followed by the item that they buy, from list above we can see costumer 1 purchased item in column 12 that marked by italic.
desire out put is :
costumer 1 purchased item 12 and item 22 and so it's for costumer 2 and
3
Note that I have try used panda and not work, and I not sure how to use if statement inside the for loop.
Also, I have used rappid minner and they replaced column by column and they included the [0][0] to be replaced. Is there any other solution beside python?
Here is my code:
import csv
csvfile = open("tran.csv", 'r')
reader = csv.reader(csvfile, delimiter=',')
my_list = list(reader)
a = len(my_list[1])
b = (my_list)
x=0
y=0
for name in my_list:
print ("costummer", my_list[0][0], "buy", my_list[n][g])
update for csv writer:
csvdict = {words[0]:words[1:] for words in csv}
for x in csvdict.keys(): # iterate over the keys '1', '2', ....
products = [index+1 for index,v in enumerate(csvdict[x]) if v == '1' ] # create list of purchases where the '1's are indexed
f = open("trans.csv", 'w')
result = ("costummer", x, "buy", products)
resultstr = (','.join([str(x) for x in hasil]))#I try to convert it to str.
print (resultstr) #to check whether the conversion from list into str is working or not.
f.write(resultstr) #try to write to csv file
Here is a "starting point", there will be an extra index for the customer 1, that is something you can play around with. It might not be important. You can add a if clause to take care of it.
csv = [['1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'], ['2', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0'], ['3', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0']]
csvdict = {words[0]:words[1:] for words in csv}
for x in sorted(csvdict.keys()): # iterate over the keys '1', '2', ....
products = [index+1 for index,v in enumerate(csvdict[x]) if v == '1' ] # create list of purchases where the '1's are indexed
print "costummer", x, "purchased", ' '.join(['"item '+str(i)+'"' for i in B])
I have a large nested loop called classarray full of information about different classes. I'm trying to combine the classes that are the same class, given that the data in the first 2 nest loop indexes are the same.
[['AAS', '100', 'Intro Asian American Studies', '0', '12', '8', '5', '1', '3', '0', '0', '0', '0', '0', '0', '0', 'S-15']
['AAS', '100', 'Intro Asian American Studies', '1', '10', '4', '3', '6', '0', '1', '2', '0', '0', '0', '0', '0', 'S-15']
['AAS', '100', 'Intro Asian American Studies', '1', '7', '6', '7', '4', '1', '0', '1', '0', '0', '0', '0', '0', 'S-15']
['AAS', '120', 'Intro to Asian Am Pop Culture', '6', '7', '5', '2', '0', '3', '3', '0', '1', '0', '0', '0', '1', 'S-15']
['AAS', '215', 'US Citizenship Comparatively', '1', '3', '5', '4', '1', '6', '1', '3', '2', '1', '1', '1', '0', 'F-15']
['AAS', '258', 'Muslims in America', '0', '19', '2', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'S-16']
['AAS', '365', 'Asian American Media and Film', '1', '4', '6', '4', '5', '1', '3', '2', '2', '0', '0', '1', '0', 'S-16']
['AAS', '365', 'Asian American Media and Film', '6', '15', '0', '0', '1', '0', '3', '1', '1', '0', '0', '0', '2', 'S-15']]
I've written this code below to try to combine the rows and produce a new array called new_array:
itemx = ['','','',0,0,0,0,0,0,0,0,0,0,0,0,0,'']
newarray=[]
for course,courseplus1 in zip(classarray,classarray[1:]):
if (course[0]==courseplus1[0] and course[1]==courseplus1[1]):
itemx[0]=course[0]
itemx[1]=course[1]
itemx[2]=course[2]
for number in range(3,16):
itemx[number]=itemx[number]+(int(course[number])+int(courseplus1[number]))
itemx[16]=course[16]
else:
newarray.append(itemx)
print(itemx)
itemx[0]=courseplus1[0]
itemx[1]=courseplus1[1]
itemx[2]=courseplus1[2]
for number in range(3,16):
itemx[number]=int(courseplus1[number])
for item in newarray:
print(item)
However, the output is this:
['AAS', '365', 'Asian American Media and Film', '7', '19', '6', '4', '6', '1', '6', '3', '3', '0', '0', '1', '2', 'S-16']
5 times.
From what I understood by looking through stack overflow, the reason is because:
newarray.append(itemx)
appends itemx to the list; itemx is one singular memory location that, at the end, has AAS 365's information in it. So, new array, as a list of itemx's, has a bunch of itemx's in it.
My question is: how do I deal with or mitigate this problem? To create classarray, I was doing the same thing, except i was declaring the itemx inside of the for loop, which i understand to mean itemx is a new variable with a new location.
>>> from copy import copy, deepcopy
help(copy)
help(deepcopy)
>>> a = [1]
>>> b = copy(a)
>>> b.append(1)
>>> b
[1, 1]
>>> a
[1]
After consulting with some experienced friends, I was able to solve my problem. All I need to do is "redeclare" itemX in my else statement after appending itemx to newarray. This points it to a new location in memory (I think)!
else:
newarray.append(itemx)
itemx = ['', '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '']
itemx[0]=courseplus1[0]
itemx[1]=courseplus1[1]
itemx[2]=courseplus1[2]
for number in range(3,16):
itemx[number]=int(courseplus1[number])