slicing a list across several slices - python

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)

Related

Compare two lists and get the indices where the values are different

I would like help with the following situation
I have two lists:
Situation 1:
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [0, 1, 2, 3, 5, 5, 6, 7, 8, 9]
I need key output: Key 4 is different
Situation 2:
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
I need key output: false -> no key is different
Situation 3:
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [0, 9, 2, 3, 4, 5, 6, 7, 3, 9]
I need key output: Key 1 and Key 8 is different
How could I resolve this? My array has 260 keys
You can use a list comprehension with zip, and enumerate to get the indices. Use short-circuiting and the fact that an empty list is falsy to get False:
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [0, 1, 2, 3, 5, 5, 6, 7, 8, 9]
out = [i for i,(e1,e2) in enumerate(zip(a,b)) if e1!=e2] or False
output:
[4]
output for example #2: False
output for example #3: [1, 8]
An approach with itertools.compress. Compare the lists to check difference in values, pass the result of the comparison to compress which will pick-up only the True ones.
from itertools import compress
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [0, 1, 2, 3, 5, 5, 6, 7, 8, 9]
result = tuple(compress(a, map(int.__ne__, a, b)))
if not result:
print(False)
else:
print(result)
The current answer is really good, but for an approach which doesn't need zip/enumerate, loop like this:
lista = []
listb = []
unequal_keys = []
for idx in range(len(lista)):
if lista[idx] != listb[idx]:
unequal_keys.append(idx)
if unequal_keys == []:
print(False)
else:
print(unequal_keys)
I recommend learning new techniques and using build ins like zip and enumerate though. They are much more pythonic and faster!

Creating duplicates in a python list

I want to repeat numbers in a list but I'm not sure how to start. Here's an example of what I'm looking to do
list1=[2,4,5,1,7,8,2,9]
list_I_want=[2,2,4,4,5,5,1,1,7,7,8,8,2,2,9,9]
I was thinking probably a for loop to do this but I am not sure where to start
Here's an easy method using nested loops in a list comprehension:
>>> list1=[2,4,5,1,7,8,2,9]
>>> [i for i in list1 for _ in range(2)]
[2, 2, 4, 4, 5, 5, 1, 1, 7, 7, 8, 8, 2, 2, 9, 9]
This is equivalent to doing nested for loops and appending in the inner loop:
>>> list_i_want = []
>>> for i in list1:
... for _ in range(2):
... list_i_want.append(i)
...
>>> list_i_want
[2, 2, 4, 4, 5, 5, 1, 1, 7, 7, 8, 8, 2, 2, 9, 9]
If you want to do it in-place (i.e. without creating a separate list), you can insert each number at its position in a loop. However, the list indexes will change as you insert new items so, performing the insertions backwards will ensure that the remaining items to process are at their expected positions:
list1=[2,4,5,1,7,8,2,9]
for i in reversed(range(len(list1))):
list1.insert(i,list1[i])
print(list1)
[2, 2, 4, 4, 5, 5, 1, 1, 7, 7, 8, 8, 2, 2, 9, 9]

Append list value by turns python [duplicate]

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)

Replace values in an array or list continuously

I am very new to coding and I was wondering if it is possible to limit an array in python to 100 items.
If it is possible, can you keep adding to that array and pushing out the old numbers in the array? So the oldest number should be pushed out to make room each time a new number is added.
Thank you very much in advance!
Yes, it's possible via collections.deque:
from collections import deque
lst = deque([], 100)
Like list.append, deque.append works in place:
A = deque(range(10), maxlen=10)
print(A)
deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
A.append(10)
print(A)
deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], maxlen=10)
What about creating a simple function to do this:
def add_to_array(lst, item, maxsize):
if len(lst) >= maxsize:
lst.pop(0)
lst.append(item)
Which works like this:
>>> lst = [i for i in range(1, 10)]
>>> lst
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> add_to_array(lst, 10, 10)
>>> lst
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> add_to_array(lst, 11, 10)
>>> lst
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Note: If your looking for something more efficient, you can use collections.deque, as pointed out in the other answer.
Here is an example of using deque to emulate your desired behaviour:
>>> lst = deque((i for i in range(1, 10)), maxlen=10)
>>> lst
deque([1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
>>> lst.append(10)
>>> lst
deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], maxlen=10)
>>> lst.append(11)
>>> lst
deque([2, 3, 4, 5, 6, 7, 8, 9, 10, 11], maxlen=10)

Extract a value out of n

How do you extract a value out of n of a list in python ?
For example :
n = 3
l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
And I would like to get
[0, 3, 6, 9]
I know I can do this with a for, but is there any more pythonic and short way ?
You can do a simple list comprehension
>>> n = 3
>>> l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [i for i in l if i%n==0]
[0, 3, 6, 9]
If your list is always like that, then you can use strides
>>> l[::3]
[0, 3, 6, 9]
Tip
Use range to generate lists like that
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Using slicing would be the most pythonic way:
In [1]: n = 3
In [2]: l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [3]: l[::n]
Out[3]: [0, 3, 6, 9]
Use a slice with stride:
l[::n]
Demo:
>>> n = 3
>>> l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> l[::n]
[0, 3, 6, 9]
print l[::3] # slice with step n = 3

Categories