I have two lists ListA and ListB as follow:
ListA=['1','1','2','2','2','3','4','4','5','5','5','5']
ListB=['1','5']
I am trying to come up with List C which has the same length as List A but replace the numbers in the List A with 'X' if the number is in the List B.The result i am expecting:
ListC=['X','X','2','2','2','3','4','4','X','X','X','X']
FYI, length of ListB will always less than the length of ListA and ListB will not hold any numbers that is not in List A.
I have tried like this:
ListA=['1','1','2','2','2','3','4','4','5','5','5','5']
ListB=['1','5']
ListC=[]
for items in ListB:
for a in ListA:
if items==a:
ListC.append('X')
else:
ListC.append(a)
obviously this will create a List that has (length of listB X lenght A) rather than just just the length of list A. Is there any built in function that does this operation? Could anyone give me a clue how to do it?
You can use a list comprehension:
[i if i not in ListB else 'X' for i in ListA]
To fix your current code, use in to check to see if the item is in ListB:
for item in ListA:
if item in ListB:
ListC.append('X')
else:
ListC.append(item)
Any time you are doing membership tests over and over on the same list, it's a good idea to create a set. Although it takes some time to construct the set the individual lookups can be much faster
SetB = set(ListB)
[i if i not in SetB else 'X' for i in ListA]
List Comprehension is your friend on this one:
ListA=['1','1','2','2','2','3','4','4','5','5','5','5']
ListB=['1','5']
ListC = [i if i not in ListB else 'x' for i in ListA]
--> ['x', 'x', '2', '2', '2', '3', '4', '4', 'x', 'x', 'x', 'x']
Hope this helps!
Related
Given a list like list1 = [[1,2,3],[4,5,6]], in order to get back [['1','2','3'],['4','5,'6']], I have tried this:
for i in list1:
for j in i:
j = str(j)
list1
which does nothing to the list: it outputs list1 unchanged. I though it would work by reassigning, something like a[0][0] = str(a[0][0]) (which does work) in a loop. Of course, the for loop above won't do that.
Also tried "map", as in
for i in list1:
for j in i:
list(map(str,i)
which also doesn absolutely nothing to list1.
I am trying to alter the original list, which should be possible. Maybe a new list would be the case, but I'm almost sure it's unnecessary.
Can someone help?
Thank you.
You can try list comprehension
[[str(j) for j in i] for i in list1]
# or
# [list(map(str,i)) for i in list1]
[['1', '2', '3'], ['4', '5', '6']]
Use nested list comperhension
list1 = [[1,2,3],[4,5,6]]
[[str(x) for x in y] for y in list1]
will return
[['1', '2', '3'], ['4', '5', '6']]
Yes, you can use map function somehow like this:
def convert(x=[]):
return [str(i) for i in x]
>>list(map(convert,x))
[['1', '2', '3'], ['4', '5', '6']]
Please check out mutable/immutable objects in Python
for i in list1: # i is a list(mutable)
for j in i: # j is an int(immutable)
j = str(j) # j reference to new string object
int is immutable (not allow changes after creation), so this line
j = str(j)
created a new string object referred by j and the object in list i remains unchanged.
list, dict, set, byte array are mutable objects.
Changing the object value in a list can be done like this:
for i in list1: # i is a list(mutable)
for j in range(len(i)): # this time, j is index of list i
i[j] = str(i[j]) # change the list values
And the result,
list1
[['1', '2', '3'], ['4', '5', '6']]
Assume I have a list=[1,2,3,4] then I want to make a list of strings which length of each string associated with corresponding value in a list.
It means the final output should be like this:
strs=['1', '11', '111', '1111']
I tried the code below but I am not sure how to continue.
lis=[1,2,3,4]
strs=[]
for i in range (len(lis)):
st=lis[i]
strs.append(st)
The multiplication for strings is repetition, so:
lst=[1,2,3,4]
result = []
for e in lst:
result.append('1'*e)
print(result)
Output
['1', '11', '111', '1111']
You first need to loop over the list of lengths lis
Then in each iteration looping n times (the given length of that iteration) and appending 1 each time to the newStr.
And after the iteration adding the newStr to the list strs
lis = [1,2,3,4]
strs = []
for n in lis:
newStr = ""
for x in range(n):
newStr += str('1')
strs.append(newStr)
I have an example:
list = [['2 a', 'nnn', 'xxxx','last'], ['next, next'], ['3', '4', 'next']]
for i in range(len(list)):
if list[i][-1] == "last":
del(list[i+1])
del(list[i])
I'd like to delete this list where the last item is "last" and the next item on the list.
In this example there is a problem every time - I tried different configurations, replacing with numpy array - nothing helps.
Trackback:
IndexError: list index out of range
I want the final result of this list to be ['3', '4', 'next']
Give me some tips or help how I can solve it.
Try this:
l = [['2 a', 'nnn', 'xxxx','last'], ['next, next'], ['3', '4', 'next']]
delete_next = False
to_ret = []
for x in l:
if x[-1] == 'last':
delete_next = True
elif delete_next:
delete_next = False
else:
to_ret.append(x)
Using a variable to store if this needs to be deleted
Loop over the list, if the last element of that iteration == 'last' then skip, else, append to a new list.
Also, it is not recommended to edit lists while iterating over them as strange things can happen, as mentioned in the comments above, like the indexes changing.
l = [['2 a', 'nnn', 'xxxx','last'], ['next, next'], ['3', '4', 'next']]
newlist = []
for i in l:
if i[-1] == 'last':
continue
else:
newlist.append(i)
I have a list like this:
list = ['aa#1#ll', 'bb#2#ff', 'cc#3#ff']
I want to convert it to a 2D list in this format
list2 = [['aa', '1', 'll'], ['bb', '2', 'ff'], ['cc', '3', 'ff']]
How can I do this in Python 3?
You can use Python's split(delimiter) method inside a generator:
list2 = [x.split("#") for x in list]
Explanation: Here, for each string x in the original list, we are calling x.split("#") on it, which will give a list of substrings that are separated by hashes in x, and we are adding the result to the list list2.
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.