l = [ [[1,2,3], [2,3,4]] ]
sum(l,[])
Output ist
[[1, 2, 3], [2, 3, 4]]
I don't know why it works like this.
I tired the two below
[].__add__(l) # First Try
[] + l # Secodn Try
In both cases, the output was as follows.
[[[1, 2, 3], [2, 3, 4]]]
I don't know what the difference is from the sum operation.
My python version is 3.8.12
sum takes a list of values and adds all of them together. E.g. for a list of numbers:
l = [1, 2, 3]
sum(l)
does:
0 + 1 + 2 + 3
As you see, the outer list does not appear in the operations nor result.
Now, with your example:
l = [ [[1,2,3], [2,3,4]] ]
sum(l, [])
that's concatenating all the values in l:
[] + [[1,2,3], [2,3,4]]
Which is not the same as:
[] + [ [[1,2,3], [2,3,4]] ]
If I understand correctly you want to add 1 to every item in the list, if so this code should work.
x = [[[1,2,3], [2,3,4]]]
for i in range(len(x[0])):
for j in range(len(x[0][i])):
x[0][i][j] += 1
print(x)
Related
I have this list of list, with a series of values:
factors = [1,2,3]
values = [[1,2,3],[3,1,4],[5,5,2]]
I want to multiply each list1 in values, but the corresponding element of list1. I am trying with this:
factors = [1,2,3]
values = [[1,2,3],[3,1,4],[5,5,2]]
multiply = []
for i in factors:
multiply = [values[i]*i]
But it does not work. The expected value would be:
[[1, 2, 3], [6, 2, 8], [15, 15, 6]]
Try this:
factors = [1, 2, 3]
values = [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
multiply = []
for idx, lst in enumerate(values):
multiply.append([factors[idx] * x for x in lst])
print(multiply)
For a list comprehension version of the above code, see #Hommes answer
Update: Given more general setup of the problem I changed the comprehension
Solution with list comprehension:
factors = [1, 2, 3]
values = [[1, 2, 3], [3, 1, 4], [5, 5, 2]]
multiply = [[factors[idx] * elem for elem in lst] for idx, lst in enumerate(values)]
Out[39]: [[1, 2, 3], [6, 2, 8], [15, 15, 6]]
There is a few problems with the code as it is:
Python uses zero-indexing
The first element of a list in Python has the index 0. In your for loop:
for i in factor:
multiply = [values[i]*i]
The last iteration will try to access values[3]. But values has only 3 elements, so the last element is values[2], not values[3].
Multiplication * of a list and an integer doesn't actually multiply
Multiplying a list by an Int, say n gives you a new list that concatenates the original n times. For example:
>>> [1, 2, 3] * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]
The most straightforward way of actually broadcasting the multiplication over the list is to use a 'list comprehension'. For example:
>>> [3*x for x in [1,2,3]]
[3, 6, 9]
Applying this into your example would look something like:
for i in factors:
multiply = [i*x for x in values[i-1]]
You are only keeping the last calculation in multiply
Each go around your for loop you assign a new value to multiply, overwriting whatever was there previously. If you want to collect all your results, then you should append to the multiply list.
multiply.append([i*x for x in values[i-1]])
All together, your example is fixed as:
factors = [1,2,3]
values = [[1,2,3],[3,1,4],[5,5,2]]
multiply = []
for i in factors:
multiply.append([i*x for x in values[i-1]])
Improvements
However, there are still ways to improve the code in terms of concision and readability.
The root of the problem is to multiply a list's elements by a number. * can't do it, but you can write your own function which can:
def multiply_list(X, n):
return [n*x for x in X]
Then you can use this function, and a list comprehension, to remove the for loop:
multiply = [multiply_list(x, i) for (x, i) in zip(values, factors)]
Or, if you think it is readable, then you can just use the nested list comprehension, which is much more concise:
multiply = [[factor * x for x in value] for (value, factor) in zip(values, factors)]
You can use list comprehension for a one liner. Try this
multiply = [[x * y for y in list1] for x in list1]
i have a flat list that i want to transform into nested list based on the defined dimension, the length of the flat list can be arbitrary, but the dimension should satisfy the length of the list, for example
[0,1,2,3,4,5,6,7]
will produce a nested list
m = 2
n = 4
[[0,1][2,3][4,5][6,7]]
or
m = 4
n = 2
[[0,1,2,3][4,5,6,7]]
i am thinking of using list comprehension to generate the nested list, but other option can also appending element from the flat list
a = [[i] * m for i in range(n)]
You can try this:
m = 2
n = 4
nums = [i*m for i in range(1,n+1)]
[list(range(x,y)) for x, y in zip([0] + nums, nums)]
OR
nums = [i*m for i in range(n)]
[list(range(z,z+m)) for z in (nums)]
Output:
[[0, 1], [2, 3], [4, 5], [6, 7]]
For
m = 4
n = 2
Output:
[[0, 1, 2, 3], [4, 5, 6, 7]]
Here's one option using list comprehensions:
col = list(range(10))
[
col[col.index(val):col.index(val) + m]
for val in col[::len(col)//n]
]
A = [[1, 2, 4],
[3, 5, 6],
[7,8,9]]
def sumof(A,3):
We need to find the lowest sum of 3 elements
here 1 + 2 + 3 = 6 so output is (1,2,3)
Can we do by using zip
one basic solution, convert nested list into flat list, sort it,slice sorted list and sum:
A = [[1, 2, 4],
[3, 5, 6],
[7,8,9]]
def sumof(A, n):
# convert nested list into flat list
flat_list = [item for sublist in A for item in sublist]
return sum(sorted(flat_list)[:n])
print (sumof(A,3))
If you have a large array, you can do this without sorting the list,
which is a little faster like
from operator import add
from functools import reduce
A = [[1, 2, 4],
[3, 5, 6],
[7,8,9]]
addlists = lambda l: reduce(add, l)
list_A = addlists(A)
result = [list_A.pop(list_A.index(min(list_A))) for _ in range(3)]
It's a little more complicated, though the modules imported are really useful.
List1=[1, 2, 2, 3]
I like the following to extract duplicate and unique list items.
DuplicateItems = [x for x in list1 if list1.count(x) > 1]
[2]
[2]
UniqueItems = [x for x in list1 if list1.count(x) == 1]
[1]
[3]
However, can I do the same with nested sequences?
List2 = [[1, 1], [2, 2], [3, 2], [3, 3]]
All list2 nested sequences containing duplicate second items should be:
[2, 2]
[3, 2]
While all list2 nested sequences unique second items should be:
[1, 1]
[3, 3]
I've tried several combinations, but it seems the following should work:
DuplicateItems = [x for x in list2 if list2.count(x[1]) > 1]
UniqueItems = [x for x in list2 if list2.count(x[1]) == 1]
It does not work. What am I doing wrong? I realize there are other methods to extract duplicate and unique items but I like the simplicity of this.
What you're doing wrong is trying to find a single number (x[1]) in a list of pairs (list2). Here's a solution you can try, using collections.Counter:
import collections
# First, extract 2nd items into new list:
counts = collections.Counter(x for _, x in list2)
# Then apply your previous logic:
duplicate_items = [x for x in list2 if counts[x[1]] > 1]
unique_items = [x for x in list2 if counts[x[1]] == 1]
Edit:
If you'd like to work with arbitrary (but equal) length nested lists (e.g: [[1, 1, 1], [2, 2, 2], ...]), assuming you're still only interested in the last element, you can replace the counts line with:
counts = collections.Counter(x for *rest, x in list2) # Python3 only, or
counts = collections.Counter(x[-1] for x in list2) # All versions of Python
Remember to update the indices in duplicate_items and unique_items too.
You can use numpy array...
import numpy as np
list2 = np.array([[1, 1], [2, 2], [3, 2], [3, 3]])
DuplicateItems = [x.tolist() for x in list2 if list2[:,1].tolist().count(x[1]) > 1]
UniqueItems = [x.tolist() for x in list2 if list2[:,1].tolist().count(x[1]) == 1]
For example, if x is [1,2,3,4] then
my program returns
[ [], [1], [1,2], [1,2,3], [1,2,3,4] ]
That would be:
[x[:i] for i in range(len(x) + 1)]
x = [1, 2, 3, 4]
print [x[:i] for i in xrange(len(x) + 1)]