I would like a one line way of assigning two variables to two different values in a for loop.
I have a list of list of values
list_values = [[1, 2, 3], [4, 5, 6]]
I have tried to do this, and it works but is not pythony:
first = [i[0] for i in list_values]
second = [i[1] for i in list_values]
Which makes:
first = [1, 4]
second = [2, 5]
I want to write something like:
first, second = [i[0]; i[1] for i in list_values]
Is something like this possible?
You could use the zip() function instead:
first, second = zip(*list_values)[:2]
or the Python 3 equivalent:
from itertools import islice
first, second = islice(zip(*list_values), 2)
zip() pairs up elements from the input lists into a sequence of new tuples; you only need the first two, so you slice the result.
list_values = [[1, 2, 3], [4, 5, 6]]
first, second = [[i[0], i[1]] for i in list_values]
Next time use something other than the "i", like "elem" etc.
Related
I have a nested list as an example:
lst_a = [[1,2,3,5], [1,2,3,7], [1,2,3,9], [1,2,6,8]]
I'm trying to check if the first 3 indices of a nested list element are the same as other.
I.e.
if [1,2,3] exists in other lists, remove all the other nested list elements that contain that. So that the nested list is unique.
I'm not sure the most pythonic way of doing this would be.
for i in range(0, len(lst_a)):
if lst[i][:3] == lst[i-1][:3]:
lst[i].pop()
Desired output:
lst_a = [[1,2,3,9], [1,2,6,8]]
If, as you said in comments, sublists that have the same first three elements are always next to each other (but the list is not necessarily sorted) you can use itertools.groupby to group those elements and then get the next from each of the groups.
>>> from itertools import groupby
>>> lst_a = [[1,2,3,5], [1,2,3,7], [1,2,3,9], [1,2,6,8]]
>>> [next(g) for k, g in groupby(lst_a, key=lambda x: x[:3])]
[[1, 2, 3, 5], [1, 2, 6, 8]]
Or use a list comprehension with enumerate and compare the current element with the last one:
>>> [x for i, x in enumerate(lst_a) if i == 0 or lst_a[i-1][:3] != x[:3]]
[[1, 2, 3, 5], [1, 2, 6, 8]]
This does not require any imports, but IMHO when using groupby it is much clearer what the code is supposed to do. Note, however, that unlike your method, both of those will create a new filtered list, instead of updating/deleting from the original list.
I think you are missing a loop For if you want to check all possibilities. I guess it should like :
for i in range(0, len(lst_a)):
for j in range(i, len(lst_a)):
if lst[i][:3] == lst[j][:3]:
lst[i].pop()
Deleting while going throught the list is maybe not the best idea you should delete unwanted elements at the end
Going with your approach, Find the below code:
lst=[lst_a[0]]
for li in lst_a[1:]:
if li[:3]!=lst[0][:3]:
lst.append(li)
print(lst)
Hope this helps!
You can use a dictionary to filter a list:
dct = {tuple(i[:3]): i for i in lst}
# {(1, 2, 3): [1, 2, 3, 9], (1, 2, 6): [1, 2, 6, 8]}
list(dct.values())
# [[1, 2, 3, 9], [1, 2, 6, 8]]
I have a 2 Dimensional list like that :
list = [[2, 3, 5], [1,2,3], [4,5,6], [8,9,10],[5,6,7]]
I can print the first value of every list with this:
[i[0] for i in list]
and outcome is:
list = [2, 1, 4, 8, 5]
but i want to have outcome like this :
list = [[2,3,5],[1,2,3],[4,5,6]]
my code is this :
new_list = []
for i in list:
row = 1
row_list = list[row]
new_list.append(row_list)
can anyone help me?
I am a bit confused what are you asking, but if I get i right try
print(list[1][1]) #print 2nd element in 2nd subset
print(list[0:3]) #print first 3 elements (in this case subsets) in the list
I hope it help.
To remove few object from list, you can use
list.remove(something) #remove element from list
or to create new list just use
l=list[0:3]
but i want to have outcome like this : list = [[2,3,5],[1,2,3],[4,5,6]]
This should do it:
list_subset = list[:3] # the first 3 elements in the list
you can slice your list like this:
n = 3 # if you have number of items you need
new_list = list[:n]
or:
n = 2 # if you have number of items you want to remove
new_list = list[:-n]
note that:
DO NOT use list as a name of a variable, list is a built-in in python.
Simple slicing can be used to skip last two rows like this:
list = [[2, 3, 5], [1,2,3], [4,5,6], [8,9,10],[5,6,7]]
print(list[:-2])
[[2, 3, 5], [1, 2, 3], [4, 5, 6]]
I want to split a list into a nest list. The list I have is this:
[1,2,1,3,2]
Now, I want the output to be like this:
[[1,2],[2,1],[1,3],[3,2]]
Is there any possible of doing the output as mentioned above?
You can use zip
lst = [1,2,1,3,2]
res = [list(pair) for pair in zip(lst, lst[1:])]
print(res) # -> [[1, 2], [2, 1], [1, 3], [3, 2]]
Note: the first instance of lst in zip does not have to be sliced since it is the smallest of the two that dictates the number of tuples that will be generated.
As #Jean-FrancoisFabre said in the comments, if the original list is big, you might want to go with a generator instead of a hard slice.
res = [list(pair) for pair in zip(lst, itertools.islice(lst, 1, None))]
The benefit of this approach (or the drawback of the previous one) is that the second list used in zip (lst[1:]) is not created in memory, but you will need to import itertools for it to work.
You're looking for bi-grams. Here is a generic function to generate n-grams from a sequence.
def ngrams(seq, n):
return [seq[i:i + n] for i in range(len(seq) - n + 1)]
a = [1,2,1,3,2]
print ngrams(a, 2)
# [[1, 2], [2, 1], [1, 3], [3, 2]]
vals= [1]
for j in xrange(i):
vals.append([k for k in f(vals[j])])
This loop appends values to itself over a loop. If I compress this into a list comprehension, it doesn't work because it doesn't "dynamically" extend vals using itself on each iteration -- it processes vals as it is originally framed.
Is there a way to do a one line list comprehension that dynamically appends like this? Based on my research, it looks like maybe I am looking for a reduce function? (the equivalent of a fold)
You can indeed use reduce for this, using the initial list as the third parameter.
>>> def f(lst):
... return [x+1 for x in lst] + [len(lst)]
>>> reduce(lambda lst, i: lst + [f(lst[i])], range(5), [[1]])
[[1], [2, 1], [3, 2, 2], [4, 3, 3, 3], [5, 4, 4, 4, 4], [6, 5, 5, 5, 5, 5]]
(Note that the initial list should probably be [[1]], not [1], otherwise you are passing a number to f in the first iteration, but a list in all following iterations.)
Also note that concerning performance your original loop is probably a bit faster, as the reduce basically has to create two new lists in each iteration, while you just have to append to a list. Personally, I would go with a variation of the loop, removing the (probably useless) inner list comprehension and using [-1] to make clear that you are always using the previous result.
vals = [[1]]
for _ in xrange(n):
vals.append(f(vals[-1]))
Let's say I have 2 arrays inside a single array, like:
main_array = [[1, 2, 3, 4], [4, 5, 6, 7]]
I would like to find the min and max of each of those arrays and store them in a single array. For the above it would be:
result = [1, 4, 4, 7]
How do I use Python's inbuilt min() and max() in this case?
I tried min(main_array) and max(main_array) but that is giving me:
result = [1,7]
You can just use min() or max() on single list to get it's min/max value. You can also use list comprehension to loop through lists in list and functions you want to use:
main_array = [[1,2,3,4], [4,5,6,7]]
res = [func(l) for l in main_array for func in (min, max)]
print(res)
main_array = [[1, 2, 3, 4], [4, 5, 6, 7]]
result = []
for inner_list in main_array:
result.append(min(inner_list))
result.append(max(inner_list))
Probably the more readable way to do it is:
result = []
for list in main_array:
result.append(min(list))
result.append(max(list))
print(result)
Try
main_array = [[1,2,3,4],[4,5,6,7]]
out = []
for arr in main_array:
out.extend([min(arr), max(arr)])
print(out)
You need to iterate over each of the sub arrays and call min and max on that.
You could also use generators
def minthenmax(arr):
for i in arr:
yield min(i)
yield max(i)
print(list(minthenmax(main_array)))
First off you're missing a common on the definition of your main array...
main_array = [[1,2,3,4],[4,5,6,7]]
To get the min of the first sub-array.
min(main_array[0])
...and the max...
max(main_array[0])
Hopefully you can work out the rest from this.
In one line. You can use build-in map function to map two inner lists to min function and then max function. Finally you can concatenate them.
map(min, main_array) + map(max, main_array)
main_array = [[1,2,3,4],[4,5,6,7]]
x = min(main_array[0]), max(main_array[0])
y = min(main_array[1]), max(main_array[1])
new_array = [i for i in x + y]
print (new_array)
output:
[1, 4, 4, 7]
You've got to search for min and max on each item of lst.
lst = [[1,2,3,4],[4,5,6,7]]
m = []
for k in lst: m.append([min(k), max(k)])
=> [[1, 4], [4, 7]]