1

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?

1
  • I reckon you would be better off with a dictionary of replacements, like {1=>X, 5=>O} and then simply newList=[dct.get(x,x) for x in oldList]. Commented May 15, 2013 at 7:08

3 Answers 3

6

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)
Sign up to request clarification or add additional context in comments.

2 Comments

Not trying to be pesky.. let's say if we have 1 more list, ListD=['O','X'] which has the same length as ListB. Assuming all the conditions on question is still applied but instead of replacing with 'X' for the match item, can we replace the match item in List A with items in List C? Which means we are still comparing List A and B but if first item of B is in A, then replace the matched item of A with first item of C. example( ListD=['O','O','2','2','2','3','4','4','X','X','X','X'])
nvm i managed to get it working by using "index" thanks a lot
5

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]

7 Comments

Ouh, that's very clever! Doesn't Python do it internally somehow without us knowing it ? I know Python sometimes does that.
Suite: Because I know Python internally does change a in [1,2,3] to a in frozenset([1,2,3]) but maybe it does this change internally each time it checks it so it might be more clever to do it manually as you purposed.
@JeromeJ no it doesn't, where did you see this? check dis.dis(lambda: a in [1, 2, 3]) it optimizes to a tuple but that's it. And yes you do need to do it manually... You are probably thinking of this: dis.dis(lambda: a in {1, 2, 3}) on Py 3
@gnibbler What about using frozenset instead of set? The set doesn't need to be changed so why not?
@JeromeJ, I don't see why since we don't need it to be hashable. Why do you think it's better?
|
4

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!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.