This question already has answers here:
How can I make a for-loop pyramid more concise in Python? [duplicate]
(4 answers)
Closed 5 years ago.
I currently have a function that creates a list of lists like below using 3 nested for-loops.
[[1,1,1] , [1,1,2] , .... , [3,3,3]]
However, the problem is I can't use this function if someone wants the list of list to be something like
[[1,1,1,1,1,1,1] , ..... , [9,9,9,9,9,9,9]]
which has more numbers (from 1 - 9) and more elements (7 of 1's instead of 4).
Here's my current code:
def listofList():
temp = []
for i in range(1,4):
for j in range(1,4):
for k in range(1,4):
temp.append([i,j,k])
return temp
Can someone provide me with a better solution? I want my function listofList() to be flexible where it could receive an input for both the size of the list of list and the elements inside the list.
Try the following:
def listofList(subLen, totalLen):
final = [[item for i in range(subLen)] for item in range(1, totalLen+1)]
return final
>>> listofList(9, 9)
[[1, 1, 1, 1, 1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 2, 2, 2, 2], [3, 3, 3, 3, 3, 3, 3, 3, 3], [4, 4, 4, 4, 4, 4, 4, 4, 4], [5, 5, 5, 5, 5, 5, 5, 5, 5], [6, 6, 6, 6, 6, 6, 6, 6, 6], [7, 7, 7, 7, 7, 7, 7, 7, 7], [8, 8, 8, 8, 8, 8, 8, 8, 8], [9, 9, 9, 9, 9, 9, 9, 9, 9]]
>>> listofList(9, 2)
[[1, 1, 1, 1, 1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 2, 2, 2, 2]]
>>> listofList(2, 9)
[[1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 7], [8, 8], [9, 9]]
>>>
Related
I would like to create a list of lists, with each sub-list increasing by 1.
In other words
[[1],
[1, 2],
[1, 2, 3],
[1, 2, 3, 4],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5, 6],
[1, 2, 3, 4, 5, 6, 7],
[1, 2, 3, 4, 5, 6, 7, 8],
[1, 2, 3, 4, 5, 6, 7, 8, 9],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
I wrote the following code, but I don't understand why list_of_lists returns the same thing 10 times in a row.
I have found examples of how to do it correctly, but I would like to understand why the code below appends the same version of the temporary list to list_of_lists, rather than appending each new version once.
list_of_lists = []
temporary = []
for i in range(1,11):
temporary.append(i)
print(temporary)
# the temporary list iterates as expected when I print it. When i is 1, it prints [1]. When i is 2, it prints [1,2]
list_of_lists.append(temporary)
print(list_of_lists)
# "list of lists" simply appends the LATEST version of "temporary" list i number of times.
My reasoning is that list_of_lists.append(temporary) should simply append 1 version of the temporary list to the end. And I don't understand why instead it overwrites the previous appended versions of the temporary list, and doesn't simply append the latest one to the already existing entries in list_of_lists
I have seen examples of how to do it correctly, so this issue is functionally solved. But I would greatly appreciate it if anyone could please take the time to explain why my logic was incorrect.
Thank you.
I was expecting:
[[1],
[1, 2],
[1, 2, 3],
[1, 2, 3, 4],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5, 6],
[1, 2, 3, 4, 5, 6, 7],
[1, 2, 3, 4, 5, 6, 7, 8],
[1, 2, 3, 4, 5, 6, 7, 8, 9],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
I got:
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
If you use list_of_lists.append(temporary), you only add a reference to the temporary list. What this means is when you print list_of_lists, it checks to see the latest version of the temporary list, and prints that. Therefore, any changes made in temporary will automatically be made in list_of_lists.
To get aroudn this, instead of appending the temporary list, you can append a copy of the list instead with temporary.copy().
Try this:
list_of_lists = []
temporary = []
for i in range(1,11):
temporary.append(i)
print(temporary)
list_of_lists.append(temporary.copy()) #this should fix it
print(list_of_lists)
This then outputs:
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6, 7], [1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
instead of:
list_of_lists.append(temporary)
you can use this:
list_of_lists.append(temporary[:])
The difference ist, that the first line only appends a reference to the list, where the second line creates a copy through [:] of the list.
I am trying to generate a list of unique lists each 5 elements long, the order is not important but there can't be any repeated elements. The first 3 elements needs to be from [1,2,3,4] and elements 4 and 5 from [5,6,7,8]. for example [1,2,3,7,8] is valid but [1,2,2,7,8] is not nor is [1,2,7,8,9]
The below code works but I am wondering is there a better way of incorporating the product function? something like d = product([L1, repeat=3][L4,repeat=2). From reading the docs the repeat keyword can only be used once, like this: d = product(L1,L4,repeat=2).
Any ideas how i could do this?
Thanks
from itertools import product
L1 = [1,2,3,4]
L2 = [1,2,3,4]
L3 = [1,2,3,4]
L4 = [5,6,7,8]
L5 = [5,6,7,8]
d = product(L1,L2,L3,L4,L5)
result=[]
for x in d:
if x.count(1)<2 and x.count(2)<2 and x.count(3)<2 and x.count(4)<2 and x.count(5)<2 and x.count(6)<2 and x.count(7)<2 and x.count(8)<2:
result.append(sorted(x))
result2 = []
for x in result:
if x not in result2:
result2.append(x)
print(result2)
result2
[[1, 2, 3, 5, 6],
[1, 2, 3, 5, 7],
[1, 2, 3, 5, 8],
[1, 2, 3, 6, 7],
[1, 2, 3, 6, 8],
[1, 2, 3, 7, 8],
[1, 2, 4, 5, 6],
[1, 2, 4, 5, 7],
[1, 2, 4, 5, 8],
[1, 2, 4, 6, 7],
[1, 2, 4, 6, 8],
[1, 2, 4, 7, 8],
[1, 3, 4, 5, 6],
[1, 3, 4, 5, 7],
[1, 3, 4, 5, 8],
[1, 3, 4, 6, 7],
[1, 3, 4, 6, 8],
[1, 3, 4, 7, 8],
[2, 3, 4, 5, 6],
[2, 3, 4, 5, 7],
[2, 3, 4, 5, 8],
[2, 3, 4, 6, 7],
[2, 3, 4, 6, 8],
[2, 3, 4, 7, 8]]
I would instead use itertools.combinations in combination with itertools.product:
from itertools import chain, combinations, product
result = list(
map(
list,
map(
chain.from_iterable,
product(
combinations([1, 2, 3, 4], 3),
combinations([5, 6, 7, 8], 2),
),
),
),
)
the repeat is going to repeat the result two times, in case anyone is wondering about it .
the product takes 1 parameter, the second is optional
for more details :
https://blog.teclado.com/python-itertools-part-1-product/
I am trying to solve this puzzle question:
There is only one five-digit number n, such that every one of the following ten numbers share exactly one digit in common in the same position as n. Find n.
I'm trying to get like this:
https://i.stack.imgur.com/hufIc.jpg
For each column, selects every element and compares it along the column if it matches the same number. And then, appends it to get which number were matched on every column.
should i add if's in here:
L = [[0, 1, 2, 6, 5],
[1, 2, 1, 7, 1],
[2, 3, 2, 5, 7],
[3, 4, 5, 4, 8],
[4, 5, 9, 7, 0],
[5, 6, 2, 3, 6],
[6, 7, 3, 2, 4],
[7, 8, 0, 8, 4],
[8, 9, 8, 7, 2],
[9, 9, 4, 1, 4]]
for c in range(10):
for r in range(5):
print(L[c][r], end=' ')
print()
The easiest way I can think of is to get all the values of a column in a variable and then check if any value occurs more than once. The solution would look something like:
L = [
[0, 1, 2, 6, 5],
[1, 2, 1, 7, 1],
[2, 3, 2, 5, 7],
[3, 4, 5, 4, 8],
[4, 5, 9, 7, 0],
[5, 6, 2, 3, 6],
[6, 7, 3, 2, 4],
[7, 8, 0, 8, 4],
[8, 9, 8, 7, 2],
[9, 9, 4, 1, 4]
]
for r in range(5):
val = [L[c][r] for c in range(10)]
for i in range(10):
if val[i] in val[:i]:
print(val[i], end=" ")
break
else:
print(0, end=" ")
print()
L = [
[0, 1, 2, 6, 5],
[1, 2, 1, 7, 1],
[2, 3, 2, 5, 7],
[3, 4, 5, 4, 8],
[4, 5, 9, 7, 0],
[5, 6, 2, 3, 6],
[6, 7, 3, 2, 4],
[7, 8, 0, 8, 4],
[8, 9, 8, 7, 2],
[9, 9, 4, 1, 4]
]
for col_index in range(5):
col= [row[col_index] for row in L]
duplicate = [x for x in col if col.count(x) > 1]
if len(duplicate) == 0:
print(0, end=" ")
else:
print(duplicate[0], end=" ")
print()
I am trying to randomly swap 2 items in each list within a list, where those to be swapped are not in another list.
Here is my code
import random
def swap(mylist):
remain = [[1, 2], [4], [], [8, 2], [1, 4], [5, 2, 1], [], [9, 5], [7]]
for x in range(0, 9):
remaining = set(mylist[x]) - set(remain[x])
to_swap = random.sample(remaining, 2)
mylist[x][mylist[x].index(to_swap[0])], mylist[x][mylist[x].index(to_swap[1])] = mylist[x][mylist[x].index(to_swap[1])], mylist[x][mylist[x].index(to_swap[0])]
return mylist
print(swap([[8, 5, 4, 1, 3, 9, 7, 6, 2], [9, 3, 5, 6, 4, 7, 1, 2, 8], [7, 3, 2, 5, 4, 1, 9, 6, 8], [2, 1, 3, 8, 6, 9, 5, 7, 4], [1, 2, 3, 5, 7, 4, 9, 8, 6], [6, 9, 3, 1, 7, 4, 2, 8, 5], [1, 2, 7, 4, 3, 8, 5, 9, 6], [3, 7, 8, 4, 1, 5, 9, 6, 2], [4, 2, 6, 5, 7, 1, 9, 3, 8]]))
Whenever I run this and print out the result, it just prints out my input again.
Does anyone know what is wrong with my code?
Thanks.
Your code performs the swaps with about one half of the sublists. I wonder what the reason of this behavior is *(see below).
If you rewrite the swapping part like this:
i = mylist[x].index(to_swap[0])
j = mylist[x].index(to_swap[1])
mylist[x][i], mylist[x][j] = mylist[x][j], mylist[x][i]
then it works.
UPDATE:
There is no need to access the lists on the right-hand side of the assignment, since we already know the values, so the updated answer would be:
i = mylist[x].index(to_swap[0])
j = mylist[x].index(to_swap[1])
mylist[x][i], mylist[x][j] = to_swap[1], to_swap[0]
*UPDATE 2:
The above mentioned behavior is caused by the fact that in multiple assignments, expressions on the left-hand side are evaluated one by one from left to right. That means the OP's code didn't work in cases where index(to_swap[0]) < index(to_swap[1]).
Example: values 5 and 6 in the first sublist [8, 5, 4, 1, 3, 9, 7, 6, 2]. First, the program will do
mylist[x][mylist[x].index(5)] = 6
modifying the list to [8, 6, 4, 1, 3, 9, 7, 6, 2]. Second, the program will do
mylist[x][mylist[x].index(6)] = 5
modifying it back to [8, 5, 4, 1, 3, 9, 7, 6, 2].
I need to filter a list of character ie
In [16]: list
Out[16]: [[1, 2, 3, 4, 5, 6, 7, 8], [2, 3, 6, 3, 6, 2, 7], [4, 5, 9, 3, 1, 8]]
characters to grep is, g = [4,8]
In [27]: a = filter(lambda x:g in x, list)
In [28]: a
Out[28]: []
But I am ending up with this. Can someone help me?
I need the output as
[[1, 2, 3, 4, 5, 6, 7, 8], [4, 5, 9, 3, 1, 8]]
Your issue is that g in x is never True because g is a list that and that is never within one of your sub-lists, e.g. ([4,8] in [4,8,7] returns False). The right approach with filter:
l = [[1, 2, 3, 4, 5, 6, 7, 8], [2, 3, 6, 3, 6, 2, 7], [4, 5, 9, 3, 1, 8]]
g = [4,8]
filter(lambda x:all(c in x for c in g), l)
# [[1, 2, 3, 4, 5, 6, 7, 8], [4, 5, 9, 3, 1, 8]]
Or list comprehension:
[item for item in l if all(c in item for c in g)]
# [[1, 2, 3, 4, 5, 6, 7, 8], [4, 5, 9, 3, 1, 8]]
Note, don't name your variables list, this shadows the built-in name