Suppose I have a list x = [1,2,3] and I want to output every other value than the indexed one, is there a list operation I can use?, ie: x[0]=> [2,3], x[1] => [1,3], x[2] =>[1,2] ?
You could use this:
def exclude(l, e):
return [v for i, v in enumerate(l) if i != e]
>>> exclude(range(10), 3)
[0, 1, 2, 4, 5, 6, 7, 8, 9]
You could do it with a slice, but I'd be tempted to try:
a = [1, 2, 3]
b = a[:]
del b[1]
edit
The above does "technically" use a slice operation, which happens to be on list objects in effect a shallow-copy.
What's more flexible and shouldn't have any downsides is to use:
a = [1, 2, 3]
b = list(a)
del b[1]
The list builtin works on any iterable (while the slice operation [:] works on lists or those that are indexable) so that you could even extend it to constructs such as:
>>> a = '123'
>>> b = list(a)
>>> del b[0]
>>> ''.join(b)
'23'
You could use x[:i] + x[i+1:]:
In [8]: x = [1, 2, 3]
In [9]: i = 0
In [10]: x[:i] + x[i+1:]
Out[10]: [2, 3]
Depending on the context, x.pop(i) might also be useful. It modifies the list in place by removing and returning the i-th element. If you don't need the element, del x[i] is also an option.
>>> x = [1, 2, 3]
>>> x[:1] + x[2:]
[1, 3]
my_list = [1, 2, 3]
my_list.remove(my_list[_index_]) #_index_ is the index you want to remove
Such that: my_list.remove(my_list[0]) would yield [2, 3],
my_list.remove(my_list[1]) would yield [0, 3], and
my_list.remove(my_list[2]) would yield [1, 2].
So you want every value except the indexed value:
Where i is the index:
>>> list = [1,2,3,4,5,6,7,8]
>>> [x for x in list if not x == list[i]]
This will give you a list with no instances of the i't element, so e.g.:
>>> i = 2
>>> list = [1,2,3,4,5,6,7,1,2,3,4,5,6,7]
>>> [x for x in list if not x == list[i]]
[1, 2, 4, 5, 6, 7, 1, 2, 4, 5, 6, 7]
note how 3 is not in that list at all.
Every other is
x[::2], start at 0
x[1::2], start at 1
Related
I have a list with elements as following:
L =[1, 2, 3, 4, 5]
I want to mirror and reorder as follows:
L =[1,5,2,4,3]
Numbers and size of elements in the list may vary and change!
Having some other examples,
K=[1, 2, 3]
Output may come out as:
K=[1, 3, 2]
And
D=[1,2,3,4]
Final results:
D = [1,4,2,3]
I have tried to do it with slice, it doesn't work for me.
You can do that by merging the list with its reverse:
lst = [1,2,3,4,5]
b = [c for a,b in zip(lst,reversed(lst)) for c in (a,b)][:len(lst)]
print(b) # [1, 5, 2, 4, 3]
Is this what you're looking for?
from random import shuffle
my_list = [1,2,3,4,5]
print (my_list)
shuffle (my_list)
print (my_list)
The following code gives you the expected output.
l = [1,2,3,4,5]
r = []
for i in range(len(l)):
if i % 2 == 0:
r.append(l[i // 2])
else:
r.append(l[-1 - i // 2])
print(r) # prints [1, 5, 2, 4, 3]
I want to reorder a list with length n, where n can be any integer between 5 and 20.
example list = [1,2,3,4,5,6]
for each one of my generated lists, I want to move the last but one element [-2] to the start of the list [0] such that the final order becomes:
new_list = [5,1,2,3,4,6]
I have tried:
myorder =[1,2,3,4,5,6]
new_order = [(myorder[-2]), [i for i in myorder[:-2]], (myorder[-1])]
but this gives me a list in a list:
[5, [1, 2, 3, 4], 6]
Is there a simple way to do this for list comprehension?
You can try this:
new_order = [myorder[-2]] + [i for i in myorder[:-2]] + [myorder[-1]]
Or, simplifying a bit,
new_order = [myorder[-2]] + myorder[:-2] + [myorder[-1]]
You can use list slicing.
Ex:
l = [1,2,3,4,5,6]
print([l[-2]] + l[:-2] + l[-1:])
Output:
[5, 1, 2, 3, 4, 6]
What about this:
>>> lst = [1, 2, 3, 4, 5, 6]
>>> lst = [lst[-2]] + lst[:-2] + [lst[-1]]
>>> lst
[5, 1, 2, 3, 4, 6]
I think this is the most general way of doing it:
example_list.insert(0, example_list.pop(-2))
You erase (pop) item -2 and insert it at position 0.
What will be the logic or code of this problem? The reverse() function does not take any argument and list[::-1] is also the same. How to do it in easy way?
Example, given:
list = [1,5,4,3,2,6]
Reversing 5...2, the output will be:
list = [1,2,3,4,5,6]
You could use list slice assignment, which modifies the list in-place:
>>> L = [1, 5, 4, 3, 2, 6]
>>> L[1:5] = L[4:0:-1]
>>> L
[1, 2, 3, 4, 5, 6]
You can reassign the slice of the list to that same slice in reverse
l = [1,5,4,3,2,6]
l[1:5] = l[1:5][::-1]
print(l)
#[1, 2, 3, 4, 5, 6]
You could do something like this:
l = [1,5,4,3,2,6]
index5 = l.index(5)
index2 = l.index(2)
l[index5:index2+1] = l[index2:index5-1:-1]
If you want it to be more explicit, you could use reversed:
l[index5:index2+1] = reversed(l[index5:index2+1])
Edit: Sorry, I misunderstood your question.
>>> l = [1, 5, 4, 3, 2, 6]
>>> temp = l[1:5]
>>> temp.reverse()
>>> l[1:5] = temp
>>> l
>>> [1, 2, 3, 4, 5, 6]
i am trying to remove duplicate values from ordered list without using IN or SET keywords
I have the following code, it removes the first occurrence of duplicates value, but not the second duplicate value
def remove_duplicates(list1):
new_list = list(list1)
indx = 0
while indx+1 < len(new_list):
if new_list[indx] == new_list[indx+1] :
new_list.pop(indx)
indx += 1
return new_list
with one duplication it works:
>>> remove_duplicates([1,2,3,3,4])
[1,2,3,4]
but not with three duplications:
>>> remove_duplicates([1,2,3,3,3,4])
[1,2,3,3,4]
as i know when you pop the value from the list it also reduces the size of by 1
any suggestions.
You can use filter function:
>>>uniq = {}
>>>filter(lambda x:uniq.update({x:1}),[1,2,3,3,3,4])
>>> print uniq.keys()
[1, 2, 3, 4]
Using dictionary keys
>>> dict.fromkeys(lst).keys()
[1, 2, 3, 5]
The trick is, that a dictionary allows only unique keys, so creating a dictionary from names with duplicated key names results in having only unique set of them.
Having list of values:
>>> lst = [1, 1, 1, 2, 3, 3, 5]
we create a dictioary using list values as keys:
>>> dct = dict.fromkeys(lst)
>>> dct
{1: None, 2: None, 3: None, 5: None}
As all the key names can be present only ones:
>>> dct.keys()
[1, 2, 3, 5]
We have what is needed.
>>> dict.fromkeys(lst).keys()
[1, 2, 3, 5]
I have to admit, that even though it is not using set, using dict keys is very similar approach.
Using generator
>>> def remove_duplicates(iterable):
... last_val = iterable.next()
... yield last_val
... for itm in iterable:
... if itm != last_val:
... last_val = itm
... yield last_val
...
>>> lst = [1, 1, 1, 2, 3, 3, 5]
>>> list(remove_duplicates(iter(lst)))
[1, 2, 3, 5]
Generator yields values one by one.
The initial value is yielded before the loop starts.
The remove_duplicates requires an iterable, so the call needs to call iter(lst) if passing a
list. Another option would be to do it inside of the generator, but my decision was to do it
outside.
The list in:
list(remove_duplicates(iter(lst)))
is to force the generator yielding all the values out.
Using groupby
In short:
>>> from itertools import groupby
>>> lst = [1, 1, 1, 2, 3, 3, 5]
>>> map(lambda grpitm: grpitm[0], groupby(lst))
[1, 2, 3, 5]
Step by step:
>>> from itertools import groupby
>>> lst = [1, 1, 1, 2, 3, 3, 5]
>>> list(groupby, lst)
[(1, <itertools._grouper at 0x7f759f976a90>),
(2, <itertools._grouper at 0x7f759f976ad0>),
(3, <itertools._grouper at 0x7f759f976b10>),
(5, <itertools._grouper at 0x7f759f976b50>)]
groupby returns an iterator, which yields tuple (groupname, grouitemiterator).
For our task, we care only about groupname:
>>> map(lambda grpitm: grpitm[0], groupby(lst))
This takes each tuple returned from groupby and pick only the first element from it.
Note, that in Pyhton 3.x you have to put map into list to see the values:
>>> list(map(lambda grpitm: grpitm[0], groupby(lst)))
My turn to try to solve that interesting "Sunday Python puzzle":
>>> def remove_duplicates(lst):
... result = [x for x,n in zip(lst,lst[1:]+[lst[0:1]]) if x != n]
... return result if result or not lst else lst[0:1]
...
>>> lst = [1, 1, 1, 2, 3, 3, 5]
>>> print remove_duplicates(lst)
[1, 2, 3, 5]
>>>
>>> lst = [5, 5]
>>> print remove_duplicates(lst)
[5]
>>>
>>> lst = [5]
>>> print remove_duplicates(lst)
[5]
>>>
>>> lst = []
>>> print remove_duplicates(lst)
[]
This answer has the property of conserving the original list order.
One might say I should have used itertools.izip. And she/he would be probably right. But, hey, its Sunday .... so let's pretend I'm using Python 3.
Try this:
def remove_duplicates(list1):
new_list = list(list1)
indx = 0
while indx+1 < len(new_list):
if new_list[indx] == new_list[indx+1] :
new_list.pop(indx)
else:
indx += 1
return new_list
The way you have it now, if you detect a duplicate as part of a triple, it will remove the middle element, then advance the index to so it's at the last element. Then, the first and the last never get compared. This way only increments the index if it doesn't detect a duplicate.
As I think there is no limit on the number of answers for this "Sunday Python Puzzle", here is my second attempt. As a matter of fact, it should have been the first, since this puzzle is a perfect candidate for reduce. I don't know how I could have missed that for so long. But, hey, it is still Sunday...
>>> def remove_duplicates(lst):
... return reduce(lambda x,n: (x + [n]) if [n] != x[-1:] else x, lst, [])
...
>>> lst = [1, 1, 1, 2, 3, 3, 5]
>>> print remove_duplicates(lst)
[1, 2, 3, 5]
>>>
>>> lst = [5, 5]
>>> print remove_duplicates(lst)
[5]
>>>
>>> lst = [5]
>>> print remove_duplicates(lst)
[5]
>>>
>>> lst = []
>>> print remove_duplicates(lst)
[]
I have a list and I want to use a certain function only on those entries of it that fulfills a certain condition - leaving the other entries unmodified.
Example: Say I want to multiply by 2 only those elements who are even.
a_list = [1, 2, 3, 4, 5]
Wanted result:
a_list => [1, 4, 3, 8, 5]
But [elem * 2 for elem in a_list if elem %2 == 0] yields [4, 8] (it acted as a filter in addition).
What is the correct way to go about it?
Use a conditional expression:
[x * 2 if x % 2 == 0 else x
for x in a_list]
(Math geek's note: you can also solve this particular case with
[x * (2 - x % 2) for x in a_list]
but I'd prefer the first option anyway ;)
a_list = [1, 2, 3, 4, 5]
print [elem*2 if elem%2==0 else elem for elem in a_list ]
or, if you have a very long list that you want to modify in place:
a_list = [1, 2, 3, 4, 5]
for i,elem in enumerate(a_list):
if elem%2==0:
a_list[i] = elem*2
so, only the even elements are modified
You could use lambda:
>>> a_list = [1, 2, 3, 4, 5]
>>> f = lambda x: x%2 and x or x*2
>>> a_list = [f(i) for i in a_list]
>>> a_list
[1, 4, 3, 8, 5]
Edit - Thinking about agf's remark I made a 2nd version of my code:
>>> a_list = [1, 2, 3, 4, 5]
>>> f = lambda x: x if x%2 else x*2
>>> a_list = [f(i) for i in a_list]
>>> a_list
[1, 4, 3, 8, 5]