I am trying to merge 2 lists like so
coordinates_X = [1, 17, 9]
coordinates_Y = [3, 5, 24]
outcome = [1, 3, 17, 5, 9, 24]
Are the lists always the same length? If so, this will give you a list of tuples:
outcome = zip(coordinates_X, coordinates_Y)
You can then flatten that:
import itertools
outcome = list(itertools.chain.from_iterable(zip(coordinates_X, coordinates_Y)))
For 2.x, itertools also has izip available, which builds an iterable yielding tuples. But that's unnecessary for lists this small. On 3.x, zip always returns an iterable.
If they're not the same length, zip or itertools.izip will truncate the outcome to match the shorter list. itertools.izip_longest can extend a shorter list with a fill value specified in the call, if you need that.
An alternate without itertools:
result = []
for i in zip(coordinates_X,coordinates_Y):
result.extend(i)
** the Code you can use is: **
coordinates_X = [1, 17, 9]
coordinates_Y = [3, 5, 24]
outcome =coordinates_X+coordinates_Y
If ordering isn't required, you can do:
coordinates_X + coordinates_Y
Also, you can use list comprehensions to output exactly what you
[ x for y in map(lambda x, y: [x, y], coordinates_X, coordinates_Y) for x in y ]
Probably not the best way to do it, but it was what occurred to me :).
Related
I have a Python list like:
mylist = [1,2,3,4,5,6,7,8]
And I want to run an operation on each two consecutive variables. For example I want to sum each two consecutive variables in the list and put them into another list:
newlist = [1+2, 3+4, 5+6, 7+8]
But how can I do that in Python? I didn't know where to start. Should I use two nested for loops, or enumerate, or zip function? I am confused.
My favorite way to do this is with an explicit list_iterator.
itr = iter(mylist)
newlist = [x + y for x, y in zip(itr, itr)]
zip advances the iterator by two elements each time it yields a pair. The benefit of using an iterator over slicing is that it doesn't require you to make two half-copies of the list before zipping.
If you don't like two lines, Python 3.8 can fold the assignment into an expression:
from operator import add
newlist = list(map(add, (i:=iter(mylist)), i))
(For some reason, you can't use an assignment expression in a list comprehension.
[x + y for x, y in zip((i:=iter(mylist)), i)]
is a syntax error, but
t = zip((i:=iter(mylist)), i)
[x + y for x, y in t]
is fine. I suspect it has something to do with scoping, but I don't know the technical details.)
Solution with zip():
out = [a+b for a, b in zip(mylist[::2], mylist[1::2])]
print(out)
Prints:
[3, 7, 11, 15]
The range() function defaults to increment the sequence by 1, but one can increment the value by adding a third parameter - range(start, stop, step_size).
You can try this:-
res = [mylist[i]+mylist[i+1] for i in range(0,len(mylist)-1, 2)]
print(res)
Output:-
[3, 7, 11, 15]
You can use this list comprehension:
mylist = [1,2,3,4,5,6,7,8]
mylist =[n+mylist[i-1] for i,n in enumerate(mylist) if i%2]
print(mylist)
Output:
[3, 7, 11, 15]
Given a list of numbers, create a new list of numbers such that the first and last numbers are added and stored as the first number, the second and second-to-last numbers are stored as the second number, and so on
num_list = [1,2,3,4,5,6]
num_list2 = [num_list[-1] + num_list[0], num_list[-2] + num_list[1],
num_list[-3] + num_list[2]]
print(num_list2)
output is [7,7,7]
I got the correct output this way but I am sure this is not an efficient way to do it. Is there a better way? I also am supposed to check for even and odd length of the list and if its an odd number of integers, add the central integer in the original list to the end of the new list but don't know how I would go about doing this
I think this is more efficient, i just simply did a for loop:
num_list2 = []
num_list = [1,2,3,4,5,6]
for i in range(round(len(num_list)/2)):
num_list2.append(num_list[i]+num_list[-(i+1)])
print(num_list2)
Output:
[7, 7, 7]
Let us using reversed
[x + y for x, y in zip(num_list, list(reversed(num_list)))][:len(num_list)//2]
Out[406]: [7, 7, 7]
Here's an inefficient[1], but clear way of doing this:
from itertools import zip_longest # or izip_longest in Python2
lst = [1,2,3,4,5,6]
chop_index = len(lst) // 2 # (or +1, depending on how you want to handle odd sized lists)
lh, rh = lst[:chop_index], lst[:chop_index-1:-1]
print(lh, rh) # To see what's going on in the "chopping"
sums = [x + y for (x,y) in zip_longest(lh, rh, fillvalue=0)]
print(sums)
You could improve it by using islice and reversed iterators, or use index math exclusively.
Output:
lst = [1,2,3,4,5,6] => [7, 7, 7]
lst = [1,2,3,4,5,6,7] => [8, 8, 8, 4]
[1] This makes two copies of the list parts. For long lists this is silly, and you shouldn't use this method. It was mostly written to highlight zip_longest's fillvalue optional argument.
Using itertools.islice on a generator:
from itertools import islice
num_list = [1,2,3,4,5,6]
generator = (x + y for x, y in zip(num_list, num_list[::-1]))
print(list(islice(generator, len(num_list)//2)))
# [7, 7, 7]
You can use the following method, which is compatible with asymmetrical list.
def sum_start_end(list_):
result = [x + y for x, y in zip(list_, list_[::-1])][:len(list_) // 2]
if len(list_) % 2 != 0:
result.append(list_[len(list_) // 2])
return result
so for a symmetric list
>>> num_list = [1, 2, 3, 4, 5, 6]
>>> sum_start_end(num_list)
[7, 7, 7]
and for asymmetric list
>>> num_list = [1, 2, 3, 4, 5, 6, 7]
>>> sum_start_end(num_list)
[8, 8, 8, 4]
It's simpler than you imagine.
Just observe your manual attempt and try to infer from it. We can simply do
x = len(num_list)//2 + len(num_list)%2
for i in range(x):
sumBoth = num_list[i] + num_list[-i-1]
num_list2.append(sumBoth)
or with a simpler one-liner
num_list2 = [ num_list[i] + num_list[-i-1] for i in range(len(num_list)//2+len(num_list)%2)]
This works for even as well as odd lengths because of the len(num_list)%2 at the end in the range.
I have a spectra of wavelengths as a list and some number of other lists I use in a formula (using tmm.tmm_core). Is there something more efficient than iterating through the wavelength if I'm just basically doing the same thing for all wavelengths?
Example
def go(n, thk, theta):
#do stuff
return(something)
wv = [1, 2, 3, 4]
a_vec = [3, 7, 3, 9]
b_vec = [6, 5, 9, 3]
c_vec = [0, 1, 8, 9]
theta = 0
th = [10, 1, 10]
final = []
for i in range(len(wv)):
n = [a[i], b[i], c[i]]
answer = go(n, th, theta)
final.append(answer)
in reality there are maybe 5000-10000 rows. It just seems to lag a bit when I press go and I assume it's because of the iteration. Pretty new to optimizing so I haven't used any benchmarking tools or anything.
I think you're looking for the map function in Python!
>>> list1 = [1,2,3,4]
>>> list2 = [5,6,7,8]
>>> map(lambda x,y: x+y, list1, list2)
[6, 8, 10, 12]
it takes in a function (in the above case, an anonymous lambda function), one or more lists and returns another list. At each iteration within the function, both lists are iterated and the result is added to the new list. You don't need to limit yourself to the expressive power of a lambda statement; you can also use globally defined functions as in the case below:
>>> def go(a,b,c):
... return a+b+c
...
>>> map(go, list1,list2, range(9,13))
[15, 18, 21, 24]
You can put all of your lists within a custom list like C_list and use map to create a new list all_len contain the length of all lists then use a list comprehension to create the list final :
all_len=map(len,C_list)
final =[[go([a[i], b[i], c[i]], th, theta) for i in range(li)] for li in all_len]
Also if the length of a and b and c are equal you can use zip function to zip then and refuse of multiple indexing :
all_len=map(len,C_list)
z=zip(a,b,c)
final =[[go(z[i], th, theta) for i in range(li)] for li in all_len]
If you have to perform an operation on every item in the list, then you're gonna have to go through every item in the list. However, you could gain speed through the use of list comprehensions: List Comprehensions
I have a nested list in python, i=[[1,2,3],[4,5,6]]. I want to sum the terms such that the final result is j=[1+4,2+5,6+3]. I have tried:
i=[[1,2,3],[4,5,6]]
j=[sum(x) for x in zip(i)]
But this is what I get instead:
>>>print j
[6, 15]
zip does not take a list of lists as an argument. It takes an arbitrary long list of list arguments.
Here is how to do it:
i=[[1,2,3],[4,5,6]]
j=[sum(x) for x in zip(*i)]
You forgot the *
>>> i=[[1,2,3],[4,5,6]]
>>> [sum(x) for x in zip(*i)]
[5, 7, 9]
How do I create a list and only extract or search out the even numbers in that list?
Create a function even_only(l) that takes a list of integers as its only argument. The
function will return a new list containing all (and only) the elements of l which are evenly divisible by 2. The original list l shall remain unchanged.
For examples, even_only([1, 3, 6, 10, 15, 21, 28]) should return [6, 10, 28], and
even_only([1, 4, 9, 16, 25]) should return [4, 16].
Hint: Start by creating an empty list, and whenever you encounter an even number in it, add it to your list, then at the end, return your list.
"By hand":
def even_only(lst):
evens = []
for number in lst:
if is_even(number):
evens.append(number)
return evens
Pythonic:
def even_only(iter):
return [x for x in iter if is_even(x)]
Since it's homework, you can fill in the is_even function.
Simplest way would be to do what you posted in a comment -- iterate through the input list to find digits evenly divisible by 2, and add them to the return list if so.
The list.append(x) function will help you add an item to a list.
Also as mentioned, look at using the modulo operation to determine if a number is divisible by 2...
The best way to do this (as a beginner) is probably a comprehension list. Since this is a homework, I won't do it for you, but here is the syntax :
[x for x in your_list if (your condition)]
You just have to replace (your condition) with what fits well (basically, exactly what you described).
P.S. I know some people may say comprehension lists are a bit advanced for a beginner, but I think it is not a concept too hard to catch and extremely useful.
>>> a = [1, 3, 6, 10, 15, 21, 28]
>>> b = [i for i in a if i%2 ==0 ]
>>> b
[6, 10, 28]
>>> a
[1, 3, 6, 10, 15, 21, 28]
>>> even_only = lambda seq : [ x for x in seq if str(x)[-1] in "02468" ]
>>> even_only([1, 3, 6, 10, 15, 21, 28])
[6, 10, 28]
Use the filter function to do this in a functional way:
>>> even_filter = lambda x: not x % 2
>>> result = filter(even_filter, [0, 1, 2, 3, 4])
>>> assert result == [0, 2, 4]
Edit: updated with the correct parity of zero per Vincent's comment.
I recently had this issue and used:
list=[1,2,3,4,5,6] #whatever your list is, just a sample
evens=[x for x in list if np.mod(x,2)==0]
print evens
returns [2,4,6]
for every element in list, if element of list modulo is 0 then number is even
initial_list = [1,22,13,41,15,16,87]
even_list = [ x for x in initial_list if x % 2 == 0]
even_list
# [22, 16]
Seems a bit late.But whats given below, works fine for me:
def even_list(*args):
# Returns the even numbers in the list
return [x for x in args if (x % 2 == 0)]
even_list(1,2,3,4,5,6,7,8)
[2, 4, 6, 8]