4

I am trying to learn python, especially lists, and I have a small problem. I have two lists:

alist=[1,2,3,4,5,6,7,8,9,1,2,3]
blist=["a","b","c","d","e","f","g","h","i","a","b","c"]

what I's like to do is remove duplicates from "both the lists". i.e only when an element of alist and its corresponding element in blist (in pairs) are the same, I delete them. I am expecting an outcome, looking like:

alist=[1,2,3,4,5,6,7,8,9]
blist=["a","b","c","d","e","f","g","h","i"]

So, I try to first do a set on the zip:

kk=set(zip(alist,blist))

and then do:

alist[:],blist[:]=zip(*kk)

then I get:

alist=[5, 6, 4, 7, 3, 8, 2, 1, 9]
blist=['e', 'f', 'd', 'g', 'c', 'h', 'b', 'a', 'i']

as you can see, the order is not maintained. I was wondering if it was possible somehow to use "sorted" and "index" to get the lists in correct order. Any guidance would be much appreciated.

The python version is 2.7.3

JohnJ
  • 6,736
  • 13
  • 49
  • 82

2 Answers2

4

You could use collections.OrderedDict for this:

In [16]: d = collections.OrderedDict.fromkeys(zip(alist, blist))

In [17]: [k[0] for k in d]
Out[17]: [1, 2, 3, 4, 5, 6, 7, 8, 9]

In [18]: [k[1] for k in d]
Out[18]: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']

An ordered set -- if it were available -- would perhaps lead to an even cleaner solution.

Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • 1
    I think you were on the right track with your now removed ordered set suggestion. It seems a fairly wasteful hack to create an ordereddict just so you can get an ordered set via the keys. – Silas Ray Jan 04 '13 at 14:25
  • @sr2222: Since you think the remark was useful, I've reinstated it. – NPE Jan 04 '13 at 14:28
  • @NPE: thanks a lot for this. However, I do not understand what you do when you do: [k[0] for k in d] Also, is this solution valid for python 2.7? .. going to try this now! – JohnJ Jan 04 '13 at 14:56
  • The soluton does work brilliantly.. but I am not entirely sure what [k[0] for k in d] and [k[1] for k in d] does in this case. I would appreciate if you could explain this a bit! – JohnJ Jan 04 '13 at 15:06
  • @JohnJ: Here, `k` iterates over every key in `d`, and `k[0]` simply extracts the first component of `k` (similarly for `k[1]`). – NPE Jan 04 '13 at 15:10
  • @NPE: How about this? d=collections.OrderedDict.fromkeys(zip(alist, blist)).keys() and then simply alist[:],blist[:]=zip(*d) – JohnJ Jan 04 '13 at 17:05
  • @JohnJ: I haven't tried it, but it looks like it should work. – NPE Jan 04 '13 at 17:43
1

use an OrderedDict:

In [1]: alist=[1,2,3,4,5,6,7,8,9,1,2,3]
In [2]: blist=["a","b","c","d","e","f","g","h","i","a","b","c"]

In [3]: from collections import OrderedDict
In [6]: od = OrderedDict().fromkeys(zip(alist, blist))

In [7]: od
Out[7]: OrderedDict([((1, 'a'), None), ((2, 'b'), None), ((3, 'c'), None), ((4, 'd'), None), ((5, 'e'), None), ((6, 'f'), None), ((7, 'g'), None), ((8, 'h'), None), ((9, 'i'), None)])
tzelleke
  • 15,023
  • 5
  • 33
  • 49
  • 1
    I think this does something different to what OP is asking. If two elements of `alist` are the same, but the corresponding elements of `blist` differ, this would only keep one pair and not both. – NPE Jan 04 '13 at 14:14
  • yeah,... you are absolutely right, I'll fix my answer -- Thanks! – tzelleke Jan 04 '13 at 14:23
  • but how fixing without copying your solution?? Can I retreat my answer?? – tzelleke Jan 04 '13 at 14:24