Append list value by turns python [duplicate] - python

This question already has answers here:
Interleave multiple lists of the same length in Python [duplicate]
(11 answers)
Closed 2 years ago.
So I'm trying to append list value to another one by turns.
This is my code:
lis1 = [1, 2, 3, 4, 5]
lis2 = [6, 7, 8, 9, 10]
for i, value in enumerate(lis2):
lis1.append(i)
print(lis1)
My expected output is [1, 6, 2, 7, 3, 8, 4, 9, 5, 10]
But what I got is [1, 2, 3, 4, 5, 0, 1, 2, 3, 4]
Any help would be appreciated

You want to use zip for this. That generates a list of tuples, and to flatten that you can use itertools.chain:
import itertools
list(zip(lis1, lis2))
# [(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)]
list(itertools.chain(*zip(lis1, lis2)))
# [1, 6, 2, 7, 3, 8, 4, 9, 5, 10]
# or:
list(itertools.chain.from_iterable(zip(lis1, lis2)))

You could do it like this:
out = []
for x in range(len(lis1)):
out.append(lis1[x])
out.append(lis2[x])
Output
[1, 6, 2, 7, 3, 8, 4, 9, 5, 10]

If you don't want to use zip from itertools, you can use list.extend() as followings:
lis1 = [1, 2, 3, 4, 5]
lis2 = [6, 7, 8, 9, 10]
new_list = []
for index, value in enumerate(lis1):
new_list.extend((lis1[index],lis2[index]))
print(new_list)

Related

How to keep adding elements from list1 to list2 until list2 is over?

For example if i have:
list1 = [1, 2, 3]
list2 = [4, 5, 6, 7, 8, 9, 10, 11, 12]
How to add elements from list1 to list2 in a loop until list2 is over, where output becomes:
list3 = [1, 4, 2, 5, 3, 6, 1, 7, 2, 8, 3, 9, 1, 10, 2, 11, 3, 12]
You can use itertools.cycle to cycle through the first list and zip the 2 lists together:
>>> from itertools import cycle
>>> [i for pair in zip(cycle(list1), list2) for i in pair]
[1, 4, 2, 5, 3, 6, 1, 7, 2, 8, 3, 9, 1, 10, 2, 11, 3, 12]
If you want to know what's going on, you can check the intermediate result:
>>> list(zip(cycle(list1), list2))
[(1, 4), (2, 5), (3, 6), (1, 7), (2, 8), (3, 9), (1, 10), (2, 11), (3, 12)]
You can remove the list comprehension and do the same thing with just builtin functions:
>>> from itertools import cycle, chain
>>> list(chain(*zip(cycle(list1), list2)))
[1, 4, 2, 5, 3, 6, 1, 7, 2, 8, 3, 9, 1, 10, 2, 11, 3, 12]
If you really want to do it in the long way:
>>> list3 = []
>>> for pair in zip(cycle(list1), list2):
... print(f'{pair=}') # just for understanding what's going on
... for i in pair:
... list3.append(i)
...
pair=(1, 4)
pair=(2, 5)
pair=(3, 6)
pair=(1, 7)
pair=(2, 8)
pair=(3, 9)
pair=(1, 10)
pair=(2, 11)
pair=(3, 12)
>>> list3
[1, 4, 2, 5, 3, 6, 1, 7, 2, 8, 3, 9, 1, 10, 2, 11, 3, 12]
You can interleave the two arrays by doing the following:
import numpy as np
list1_tiled = np.tile([1, 2, 3], 3)
list2 = np.array([4, 5, 6, 7, 8, 9, 10, 11, 12])
np.ravel(np.column_stack((list1_tiled, list2)))
Output:
array([ 1, 4, 2, 5, 3, 6, 1, 7, 2, 8, 3, 9, 1, 10, 2, 11, 3, 12])
If you want a really simple, no import solution, you can just continuously rotate out the first element in your first list.
list1 = [1, 2, 3]
list2 = [4 ,5 ,6, 7, 8, 9, 10, 11, 12]
list3 = []
for i in list2:
list3.extend([list1[0], i])
# this pops the first element from your list
# and appends it to the end.
list1.append(list1.pop(0))
print(list3)
This essentially makes list1 an infinitely rotating list, sort of like collections.deque.

slicing a list across several slices

I'm looking to slice a list across two or more slices. For example, there is a list:
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Let's say I want to slice the list as items 1 to 4 and 6 to 9.
If we do:
a[1:5]
the output:
[1, 2, 3, 4]
If we do:
a[6:10]
the output is:
[6, 7, 8, 9]
But is there someway to combine multiple slices. Something like:
a[1:5 and 6:10]
to output:
[1, 2, 3, 4, 6, 7, 8, 9]
There is no special syntax, just append the lists slices:
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# [1, 2, 3, 4, 6, 7, 8, 9]
print(a[1:5]+a[6:10])
If you want to avoid creating the intermediate lists for the individual slices, you could use itertools.islice and chain.from_iterable to get and combine the slices as iterators.
>>> from itertools import chain, islice
>>> slc = [(1,5), (6,10)]
>>> list(chain.from_iterable(islice(a, *s) for s in slc))
[1, 2, 3, 4, 6, 7, 8, 9]
Also works with 1- or 3-tuples, for just end-, or start-end-step slices.
Based on napuzba's suggestion, I'm thinking that the following might be the most efficient way to do this:
all_slice = [*a[1:5], *a[6:10]]
Where all_slice holds:
[1, 2, 3, 4, 6, 7, 8, 9]
This seems pretty pythonic.
You can use list.extend for this task.
slice1 = a[1:5]
slice2 = a[6:10]
slice1.extend(slice2)
# now use slice1
It appends all the items of the slice2 to the first slice1.
If you have several ranges you are trying to slice, you can use the built-in slice() with a list comprehension:
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
ranges = [(1, 5), (6, 10)]
[n for s in ranges for n in a[slice(*s)]]
# [1, 2, 3, 4, 6, 7, 8, 9]
Inspired by the answer:
There is no special syntax, just append the lists slices:
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(a[1:5]+a[6:10])
FROM -> Aviv Yaniv
b, a = a[1:5], a[6:10]
print(b+a)

How do I split the values in Python list at regular intervals? [duplicate]

This question already has answers here:
How do I split a list into equally-sized chunks?
(66 answers)
How to iterate over a list in chunks
(39 answers)
Closed 3 years ago.
Here's a list like this.
mylist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
I want to split this list every 4 intervals.
In other words, I want to make it like this.
  [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]
I want to divide the list and save it.
Is there a function that provides this partitioning capability?
for i in range(len(mylist)):
if(i+1)%4 == 0:
print(mylist[i-3:i+1])
You can use zip and iter like this, to split the list into sublists
>>> mylist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>>> list(zip(*([iter(mylist)]*4)))
[(1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)]
>>>
>>> list(map(list, zip(*([iter(mylist)]*4))))
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]

Printing a list after having removed adjacent duplicate elements

new_list = []
i = 0
def remove_adjacent(nums):
global i
while i < len(nums) - 1:
if nums[i] != nums[i+1]:
new_list.append(nums[i])
else:
i += 1
remove_adjacent(nums[i:])
return
i += 1
l = [1, 2, 3, 5, 4, 4, 5, 5, 6, 7, 7, 7, 8, 8, 9, 8, 8]
remove_adjacent(l)
print new_list
Question: Given a list of numbers, return a list where all adjacent == elements have been reduced to a single element, so [1, 2, 2, 3] returns [1, 2, 3]. You may create a new list or modify the passed in list.
Issue: The final list printed consists of [1, 2, 3, 5] instead of [1, 2, 3, 5, 4, 5, 6, 7, 8, 9, 8]
What you would want is a problem best solved by itertools.groupby
l
Out[35]: [1, 2, 3, 5, 4, 4, 5, 5, 6, 7, 7, 7, 8, 8, 9, 8, 8]
from itertools import groupby
[k for k, _ in groupby(l)]
Out[36]: [1, 2, 3, 5, 4, 5, 6, 7, 8, 9, 8]
What itertools.groupby does is, it groups consecutive keys together by generating a tuple of the element and the consecutive group as a list
To get a clear understanding of itertools.groupby, you can dump the resultant list of tuples generated by grouping the list of consecutive numbers
[(k, list(g)) for k, g in groupby(l)]
Out[40]:
[(1, [1]),
(2, [2]),
(3, [3]),
(5, [5]),
(4, [4, 4]),
(5, [5, 5]),
(6, [6]),
(7, [7, 7, 7]),
(8, [8, 8]),
(9, [9]),
(8, [8, 8])]
new_list = []
def remove_adjacent(nums):
i = 0
while i < len(nums) - 1:
if nums[i] != nums[i+1]:
new_list.append(nums[i])
else:
i += 1
remove_adjacent(nums[i:])
return
i += 1
l = [1, 2, 3, 5, 4, 4, 5, 5, 6, 7, 7, 7, 8, 8, 9, 8, 8]
remove_adjacent(l)
# appending the last item
new_list.append(l[len(l)-1])
print (new_list.append(nums[len(nums) - 1]))
Output
[1, 2, 3, 5, 4, 5, 6, 7, 8, 9, 8]
This is perfect for a generator. I'm not altering the original list. Instead, I'm returning a new list with no adjacent values equal to one another.
def removerator(l):
last = None
for x in l:
if x != last:
last = x
yield x
list(removerator(l))
[1, 2, 3, 5, 4, 5, 6, 7, 8, 9, 8]
Setup
l = [1, 2, 3, 5, 4, 4, 5, 5, 6, 7, 7, 7, 8, 8, 9, 8, 8]
I made a function where it get a list and iterate over its items, then it adds the items that aren't the same as the items already added to the list in the previous iteration.
l = [1, 2, 3, 5, 4, 4, 5, 5, 6, 7, 7, 7, 8, 8, 9, 8, 8] # List that we want to change
def remove_adjacent(l): # Define a new function and accept an argument: the list to check.
new = [l[0]] # Make a new list (temporal) and assing like it's first item the first item of the main list. It's the same as new = [] and new.append(l[0]).
for item in l[1:]: # We iterate across the list, but we don't iterate on the first item because we've alreaday added it to the list, if you want you can delete the slice in [1:] since it will only make the iteration a really small fraction more slowly.
if new[-1] != item: # We check if the new item is the same as the last item added to the new list, if not, we add it.
new.append(item) # We add the item to the new list.
return new # We return the list.
print(remove_adjacent(l)) # We check it.
# [1, 2, 3, 5, 4, 5, 6, 7, 8, 9, 8]

How to add two list up in alternate positions? - python [duplicate]

This question already has answers here:
Round Robin method of mixing of two lists in python
(9 answers)
Closed 8 years ago.
How to add two list up in alternate positions?
E.g. I have:
>>> x = [1,3,5,7,9]
>>> y = [2,4,6,8,10]
and when i add the list up, i get:
>>> x + y
[1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
but the desired output is:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
I have tried this but is there other way to achieve the desired output?
>>> z = []
>>> for i,j in zip(x,y):
... z.append(i)
... z.append(j)
...
>>> z
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
You can use zip and a list comprehension:
>>> x = [1, 3, 5, 7, 9]
>>> y = [2, 4, 6, 8, 10]
>>> [b for a in zip(x, y) for b in a]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>>
zip(x, y) is used to pair up the items in x and y:
>>> x = [1, 3, 5, 7, 9]
>>> y = [2, 4, 6, 8, 10]
>>> list(zip(x, y))
[(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
>>>
If you are using Python 2.x though, you may want to replace it with itertools.izip(x, y) so that you do not create a list unnecessarily.

Categories