Altering list while iterating - python

Python noob here. I have a list of numbers represented as strings. Single digit numbers are represented with a zero and I'm trying to get rid of the zeroes. For instance, ['01', '21', '03'] should be ['1', '21', '3'].
My current solution seems a bit clumsy:
for item in list:
if item[0] == '0':
list[list.index(item)] = item[1]
I'm wondering why this doesn't work:
for item in list:
if item[0] == '0':
item = item[1]

Rebinding the iterating name does not mutate the list.
Also:
>>> [str(int(x, 10)) for x in ['01', '21', '03']]
['1', '21', '3']

You could try stripping the zero:
>>> map(lambda x: x.lstrip('0'), ['001', '002', '030'])
['1', '2', '30']

To mutate the list:
for i, item in enumerate(mylist):
if item.startswith('0'):
mylist[i] = item[1:]
Better is probably just to create a new list:
new_list = [x.lstrip('0') for x in mylist]
Your code doesn't work because assigning to item merely gives the name item a new value, it doesn't do anything to the old value of item.

The code "item" is a variable that contains the value of the item as you iterate through the list. It has no reference to the list itself.
Your first solution is very slow because it will have to search the list for each item to find the index.
See other answers for examples of how to accomplish what you want.

Related

Delete even indexes out of range [duplicate]

I'm trying to remove the odd-indexed elements from my list (where zero is considered even) but removing them this way won't work because it throws off the index values.
lst = ['712490959', '2', '623726061', '2', '552157404', '2', '1285252944', '2', '1130181076', '2', '552157404', '3', '545600725', '0']
def remove_odd_elements(lst):
i=0
for element in lst:
if i % 2 == 0:
pass
else:
lst.remove(element)
i = i + 1
How can I iterate over my list and cleanly remove those odd-indexed elements?
You can delete all odd items in one go using a slice:
del lst[1::2]
Demo:
>>> lst = ['712490959', '2', '623726061', '2', '552157404', '2', '1285252944', '2', '1130181076', '2', '552157404', '3', '545600725', '0']
>>> del lst[1::2]
>>> lst
['712490959', '623726061', '552157404', '1285252944', '1130181076', '552157404', '545600725']
You cannot delete elements from a list while you iterate over it, because the list iterator doesn't adjust as you delete items. See Loop "Forgets" to Remove Some Items what happens when you try.
An alternative would be to build a new list object to replace the old, using a list comprehension with enumerate() providing the indices:
lst = [v for i, v in enumerate(lst) if i % 2 == 0]
This keeps the even elements, rather than remove the odd elements.
Since you want to eliminate odd items and keep the even ones , you can use a filter as follows :
>>>filtered_lst=list(filter(lambda x : x % 2 ==0 , lst))
this approach has the overhead of creating a new list.

How to compare each element of multiple lists and return name of lists which are different

I am having multiple lists and I need to compare each list with one another and return the name of lists which are different. We need to consider value of elements in list irrespective of their position while comparing lists.
For example:-
Lis1=['1','2','3']
Lis2=['1','2']
Lis3=['0','1','3']
Lis4=[]
Lis5=['1','2']
Output:-
['Lis1','Lis2','Lis3','Lis4']
Thanks in advance.
Try this:
input_lists = {"Lis1": ['1', '2', '3'], "Lis2": ['1', '2'],
"Lis3": ['0', '1', '3'], "Lis4": [], "Lis5": ['1', '2']}
output_lists = {}
for k, v in input_lists.items():
if sorted(v) not in output_lists.values():
output_lists[k] = sorted(v)
unique_keys = list(output_lists.keys())
print(unique_keys) # ['Lis1', 'Lis2', 'Lis3', 'Lis4']
import itertools
Lis1=['1','2','3']
Lis2=['1','2']
Lis3=['0','1','3']
Lis4=[]
Lis5=['1','2']
k=[Lis1,Lis2,Lis3,Lis4,Lis5]
k.sort()
list(k for k,_ in itertools.groupby(k))
output
[[], ['0', '1', '3'], ['1', '2'], ['1', '2', '3']]
a simple way to implement
Lis1=['1','2','3']
Lis2=['1','2']
Lis3=['0','1','3']
Lis4=[]
Lis5=['1','2']
lis=[Lis1,Lis2,Lis3,Lis4,Lis5]
final=[]
for ele in lis:
if(ele not in final):
final.append(ele)
print(final)
with your given data you can use:
Lis1=['1','2','3']
Lis2=['1','2']
Lis3=['0','1','3']
Lis4=[]
Lis5=['1','2']
name_lis = {'Lis1': Lis1, 'Lis2': Lis2, 'Lis3': Lis3, 'Lis4': Lis4, 'Lis5': Lis5}
tmp = set()
response = []
for k, v in name_lis.items():
s = ''.join(sorted(v))
if s not in tmp:
tmp.add(s)
response.append(k)
print(response)
output:
['Lis1', 'Lis2', 'Lis3', 'Lis4']
name_lis dictionary contains the name of your list and the actual list, you are iterating over each list, and for each list, you are sorting the elements and then converting in a string, if the string was encountered before you know that the list is a duplicate if not you are adding the list to the response

How to remove preceding zeros in a string element from a Python list

I have a list:
my_list = ['0300', '0023', '0005', '000030']
I want to remove the preceding zeroes in each string element from the list. So I want strip the 0s from the left side of the string.
Output would be like this:
my_list = ['300', '23', '5', '30']
I've tried this:
for x in my_list:
x = re.sub(r'^0+', "", x)
print my_list
But it doesn't seem to work. Please help!
You can use str.lstrip like this
print [item.lstrip('0') for item in l]
# ['300', '23', '5', '30']
Try:
list = [str(int(el)) for el in list]
Edit: pick the other answer, I'd prefer that one too :-)

Subtract items in a single list and retrieve items that match a condition

I recently asked a question regarding the retrieval of differences between two lists that meet a condition, but I keep failing to alter the EXAMPLE LAMBDA EXPRESSION below to do the same for the items in a single list:
A = ['12', '15', '20', '30']
filter(lambda a: all([abs(int(a) - int(b)) >= 5 for b in List1]), List2)
Where my list is sorted and can have varied lengths. The goal is to change the above expression in order to retrieve only those items with a difference TO ANY OTHER ITEM in the list is less than or equal to 5.
Where the output working on the list above should be:
newAList = ['12', '15', '20']
This is a shorter version:
>>> A = ['12', '15', '20', '30']
>>> [x for x in A if len(A) == 1 or filter(lambda y: 0 < abs(int(y) - int(x)) <= 5,A)]
['12', '15', '20']
>>>
Based on your comments, I believe the following list comprehension should do what you are looking for. The key parts are:
Using any instead of all to check whether any item exists that is at most 5 smaller or larger than the current one being looked at
Using enumerate to ensure the condition ignores the item currently being looked at - you can remove the calls to enumerate and change the comparison to 0 < abs(int(a) - int(b)) <= 5 if you know there are no duplicates
Using a list comprehension instead of filter to make it more readable, in my opinion (only just) - it should be possible to do the same thing with filter, however
The code:
>>> A = ['12', '15', '20', '30']
>>> [a for i, a in enumerate(A) if any(j != i and abs(int(a) - int(b)) <= 5 for j, b in enumerate(A))]
['12', '15', '20']
I bet this will be quite inefficient for any list much larger than this one, however, since you will be iterating over the list once for every item in the list. Hopefully it is enough to give you a starting point, however.

How can I split a list into smaller lists?

I have a list:
lists = (['1','2','3','S','3','4','S','4','6','7'])
And I want to split the list into s smaller list everytime 'S' appears and eliminate 'S' into something like:
([['1','2','3'],['3','4],['4','6','7']])
My code:
def x (lists):
empty = ''
list = []
for x in lists:
if x == empty:
list[-1:].append(x)
else:
list.append([x])
return (list)
I tried something like this, but I am quite new to python, and Im getting nowhere. Nothing fancy please, how would I fix what I have?
Try itertools.groupby():
>>> from itertools import groupby
>>> lists = ['1','2','3','S','3','4','S','4','6','7']
>>> [list(g[1]) for g in groupby(lists, lambda i:i!='S') if g[0]]
[['1', '2', '3'], ['3', '4'], ['4', '6', '7']]
Maybe something like map(list,''.join(lists).split('S'))
Alternately, [list(s) for s in ''.join(lists).split('S'))
Well, may be funny, but this should work:
[s.split('#') for s in '#'.join(lists).split('#S#')]
Instead of the '#' any character can be used if it's unlikely to appear in lists.

Categories

Resources