Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > newbie/ merging lists of lists with items in common

Reply
Thread Tools

newbie/ merging lists of lists with items in common

 
 
ardief
Guest
Posts: n/a
 
      02-02-2007
Hi everyone
Here is my problem:
I have a list that looks like this -
[['a', '13'], ['a', '3'], ['b', '6'], ['c', '12'], ['c', '15'], ['c',
'4'], ['d', '2'], ['e', '11'], ['e', '5'], ['e', '16'], ['e', '7']]

and I would like to end up with something like this, i.e. with the
only one list per letter:

[['a', ['13' '3']], ['b', '6'], ['c', ['12', '15', '4']], ['d', '2'],
['e', ['11', '5', '16', '7']]]

I have the feeling it's trivial, and I've scoured the group archives -
sets might be a possibility, but I'm not sure how to operate on a list
of lists with sets.

This function also gives me what I want, more or less, but I don't
know how to make it run until it's covered all the possibilities, if
that makes sense...

def sigh(list):
for a in list:
i = list.index(a)
if a != list[-1]: ##if a is not the last one, i.e. there is a
next one
n = alist[i+1]
if a[0] == n[0]:
a.append(n[1:])
del alist[i+1]

Sorry about the lengthy message and thanks for your suggestions - I'm
trying to learn...

 
Reply With Quote
 
 
 
 
Miki
Guest
Posts: n/a
 
      02-02-2007
Hello,
> Here is my problem:
> I have a list that looks like this -
> [['a', '13'], ['a', '3'], ['b', '6'], ['c', '12'], ['c', '15'], ['c',
> '4'], ['d', '2'], ['e', '11'], ['e', '5'], ['e', '16'], ['e', '7']]
>
> and I would like to end up with something like this, i.e. with the
> only one list per letter:
>
> [['a', ['13' '3']], ['b', '6'], ['c', ['12', '15', '4']], ['d', '2'],
> ['e', ['11', '5', '16', '7']]]

I'd use a dictionary to store value for a given key:
>>> def aggregate(lst):

items = {} # key -> values
for key, value in lst:
values = items.get(key)
if values:
if type(values) == list:
values.append(value)
else:
items[key] = [values, value]
else:
items[key] = value
return[list(pair) for pair in items.items()]

>>> aggregate(lst)

[['a', ['13', '3']], ['c', ['12', '15', '4']], ['b', '6'], ['e',
['11', '5', '16', '7']], ['d', '2']]
>>>


HTH,
--
Miki <(E-Mail Removed)>
http://pythonwise.blogspot.com

 
Reply With Quote
 
 
 
 
Larry Bates
Guest
Posts: n/a
 
      02-02-2007
ardief wrote:
> Hi everyone
> Here is my problem:
> I have a list that looks like this -
> [['a', '13'], ['a', '3'], ['b', '6'], ['c', '12'], ['c', '15'], ['c',
> '4'], ['d', '2'], ['e', '11'], ['e', '5'], ['e', '16'], ['e', '7']]
>
> and I would like to end up with something like this, i.e. with the
> only one list per letter:
>
> [['a', ['13' '3']], ['b', '6'], ['c', ['12', '15', '4']], ['d', '2'],
> ['e', ['11', '5', '16', '7']]]
>
> I have the feeling it's trivial, and I've scoured the group archives -
> sets might be a possibility, but I'm not sure how to operate on a list
> of lists with sets.
>
> This function also gives me what I want, more or less, but I don't
> know how to make it run until it's covered all the possibilities, if
> that makes sense...
>
> def sigh(list):
> for a in list:
> i = list.index(a)
> if a != list[-1]: ##if a is not the last one, i.e. there is a
> next one
> n = alist[i+1]
> if a[0] == n[0]:
> a.append(n[1:])
> del alist[i+1]
>
> Sorry about the lengthy message and thanks for your suggestions - I'm
> trying to learn...
>

One solution:

l=[['a', '13'], ['a', '3'], ['b', '6'], ['c', '12'], ['c', '15'], ['c','4'],
['d', '2'], ['e', '11'], ['e', '5'], ['e', '16'], ['e', '7']]
d={}
for k, v in l:
if d.has_key(k): d[k].append(v)
else: d[k]=[v]
print "d=", d

l=[x for x in d.items()]
print l


-Larry
 
Reply With Quote
 
Paddy
Guest
Posts: n/a
 
      02-02-2007
On Feb 2, 1:55 pm, "ardief" <(E-Mail Removed)> wrote:
> Hi everyone
> Here is my problem:
> I have a list that looks like this -
> [['a', '13'], ['a', '3'], ['b', '6'], ['c', '12'], ['c', '15'], ['c',
> '4'], ['d', '2'], ['e', '11'], ['e', '5'], ['e', '16'], ['e', '7']]
>
> and I would like to end up with something like this, i.e. with the
> only one list per letter:
>
> [['a', ['13' '3']], ['b', '6'], ['c', ['12', '15', '4']], ['d', '2'],
> ['e', ['11', '5', '16', '7']]]
>
> I have the feeling it's trivial, and I've scoured the group archives -
> sets might be a possibility, but I'm not sure how to operate on a list
> of lists with sets.
>
> This function also gives me what I want, more or less, but I don't
> know how to make it run until it's covered all the possibilities, if
> that makes sense...
>
> def sigh(list):
> for a in list:
> i = list.index(a)
> if a != list[-1]: ##if a is not the last one, i.e. there is a
> next one
> n = alist[i+1]
> if a[0] == n[0]:
> a.append(n[1:])
> del alist[i+1]
>
> Sorry about the lengthy message and thanks for your suggestions - I'm
> trying to learn...


: python
Python 2.5 (r25:51908, Nov 28 2006, 16:10:01)
[GCC 3.4.3 (TWW)] on sunos5
Type "help", "copyright", "credits" or "license" for more information.
>>> from pprint import pprint as pp
>>> from collections import defaultdict
>>> data = [['a', '13'], ['a', '3'], ['b', '6'], ['c', '12'], ['c', '15'], ['c', '4'], ['d', '2'], ['e', '11'], ['e', '5'], ['e', '16'], ['e', '7']]
>>> d = defaultdict(list)
>>> _ = [d[x0].append(x1) for x0,x1 in data]
>>> pp(d)

defaultdict(<type 'list'>, {'a': ['13', '3'], 'c': ['12', '15', '4'],
'b': ['6'], 'e': ['11', '5', '16', '7'], 'd': ['2']})
>>> pp(sorted(d.items()))

[('a', ['13', '3']),
('b', ['6']),
('c', ['12', '15', '4']),
('d', ['2']),
('e', ['11', '5', '16', '7'])]
>>>


- Paddy

 
Reply With Quote
 
Neil Cerutti
Guest
Posts: n/a
 
      02-02-2007
On 2007-02-02, ardief <(E-Mail Removed)> wrote:
> Hi everyone
> Here is my problem:
> I have a list that looks like this -
> [['a', '13'], ['a', '3'], ['b', '6'], ['c', '12'], ['c', '15'], ['c',
> '4'], ['d', '2'], ['e', '11'], ['e', '5'], ['e', '16'], ['e', '7']]
>
> and I would like to end up with something like this, i.e. with
> the only one list per letter:
>
> [['a', ['13' '3']], ['b', '6'], ['c', ['12', '15', '4']], ['d', '2'],
> ['e', ['11', '5', '16', '7']]]
>
> I have the feeling it's trivial, and I've scoured the group
> archives - sets might be a possibility, but I'm not sure how to
> operate on a list of lists with sets.


This is a job for... duhn-duhn-DAAAAH! Captain CHAOS!

Er... I mean itertools.groupby.

I took the liberty of not assuming the alist was sorted already.
This could be a one-liner if you wanted to be evil.

def bundle_alist(seq):
""" Bundle together some alist tails.

>>> seq = [['a', '13'], ['a', '3'], ['b', '6'], ['c', '12'], ['c', '15'], ['c', '4'], ['d', '2'], ['e', '11'], ['e', '5'], ['e', '16'], ['e', '7']]
>>> bundle_alist(seq)

[['a', ['13', '3']], ['b', ['6']], ['c', ['12', '15', '4']], ['d', ['2']], ['e', ['11', '5', '16', '7']]]

"""
from itertools import groupby
def key_func(t):
return t[0]
groups = groupby(sorted(seq, key=key_func), key_func)
seq = []
for item in groups:
seq.append([item[0], [a[1] for a in item[1]]])
return seq


--
Neil Cerutti
Music gets more chromatic and heavy towards the end of the century. One of the
popular questions of the day was, "Why?" --Music Lit Essay
 
Reply With Quote
 
Laurent Pointal
Guest
Posts: n/a
 
      02-02-2007
ardief a écrit :
> Hi everyone
> Here is my problem:
> I have a list that looks like this -
> [['a', '13'], ['a', '3'], ['b', '6'], ['c', '12'], ['c', '15'], ['c',
> '4'], ['d', '2'], ['e', '11'], ['e', '5'], ['e', '16'], ['e', '7']]
>
> and I would like to end up with something like this, i.e. with the
> only one list per letter:
>
> [['a', ['13' '3']], ['b', '6'], ['c', ['12', '15', '4']], ['d', '2'],
> ['e', ['11', '5', '16', '7']]]
>
> I have the feeling it's trivial, and I've scoured the group archives -
> sets might be a possibility, but I'm not sure how to operate on a list
> of lists with sets.
>
> This function also gives me what I want, more or less, but I don't
> know how to make it run until it's covered all the possibilities, if
> that makes sense...
>
> def sigh(list):
> for a in list:
> i = list.index(a)
> if a != list[-1]: ##if a is not the last one, i.e. there is a
> next one
> n = alist[i+1]
> if a[0] == n[0]:
> a.append(n[1:])
> del alist[i+1]
>
> Sorry about the lengthy message and thanks for your suggestions - I'm
> trying to learn...
>


You may take a look to the groupby iterator in the standard itertools
module.

http://docs.python.org/lib/itertools-functions.html
 
Reply With Quote
 
Paddy
Guest
Posts: n/a
 
      02-02-2007
On Feb 2, 2:39 pm, "Paddy" <(E-Mail Removed)> wrote:
> On Feb 2, 1:55 pm, "ardief" <(E-Mail Removed)> wrote:
>
>
>
> > Hi everyone
> > Here is my problem:
> > I have a list that looks like this -
> > [['a', '13'], ['a', '3'], ['b', '6'], ['c', '12'], ['c', '15'], ['c',
> > '4'], ['d', '2'], ['e', '11'], ['e', '5'], ['e', '16'], ['e', '7']]

>
> > and I would like to end up with something like this, i.e. with the
> > only one list per letter:

>
> > [['a', ['13' '3']], ['b', '6'], ['c', ['12', '15', '4']], ['d', '2'],
> > ['e', ['11', '5', '16', '7']]]

>
> > I have the feeling it's trivial, and I've scoured the group archives -
> > sets might be a possibility, but I'm not sure how to operate on a list
> > of lists with sets.

>
> > This function also gives me what I want, more or less, but I don't
> > know how to make it run until it's covered all the possibilities, if
> > that makes sense...

>
> > def sigh(list):
> > for a in list:
> > i = list.index(a)
> > if a != list[-1]: ##if a is not the last one, i.e. there is a
> > next one
> > n = alist[i+1]
> > if a[0] == n[0]:
> > a.append(n[1:])
> > del alist[i+1]

>
> > Sorry about the lengthy message and thanks for your suggestions - I'm
> > trying to learn...

>
> : python
> Python 2.5 (r25:51908, Nov 28 2006, 16:10:01)
> [GCC 3.4.3 (TWW)] on sunos5
> Type "help", "copyright", "credits" or "license" for more information.>>> from pprint import pprint as pp
> >>> from collections import defaultdict
> >>> data = [['a', '13'], ['a', '3'], ['b', '6'], ['c', '12'], ['c', '15'], ['c', '4'], ['d', '2'], ['e', '11'], ['e', '5'], ['e', '16'], ['e', '7']]
> >>> d = defaultdict(list)
> >>> _ = [d[x0].append(x1) for x0,x1 in data]
> >>> pp(d)

>
> defaultdict(<type 'list'>, {'a': ['13', '3'], 'c': ['12', '15', '4'],
> 'b': ['6'], 'e': ['11', '5', '16', '7'], 'd': ['2']})>>> pp(sorted(d.items()))
>
> [('a', ['13', '3']),
> ('b', ['6']),
> ('c', ['12', '15', '4']),
> ('d', ['2']),
> ('e', ['11', '5', '16', '7'])]
>
>
>
> - Paddy



Use defaultdict(set) and d[x0].add(x1) if you also want to remove
duplicates.

- Paddy.

 
Reply With Quote
 
Bart Ogryczak
Guest
Posts: n/a
 
      02-02-2007
On Feb 2, 2:55 pm, "ardief" <(E-Mail Removed)> wrote:
> Hi everyone
> Here is my problem:
> I have a list that looks like this -
> [['a', '13'], ['a', '3'], ['b', '6'], ['c', '12'], ['c', '15'], ['c',
> '4'], ['d', '2'], ['e', '11'], ['e', '5'], ['e', '16'], ['e', '7']]
>
> and I would like to end up with something like this, i.e. with the
> only one list per letter:
>
> [['a', ['13' '3']], ['b', '6'], ['c', ['12', '15', '4']], ['d', '2'],
> ['e', ['11', '5', '16', '7']]]


your_list = [['a', '13'], ['a', '3'], ['b', '6'], ['c', '12'], ['c',
'15'], ['c', '4'], ['d', '2'], ['e', '11'], ['e', '5'], ['e', '16'],
['e', '7']]
d = {}
for k,v in your_list: d.setdefault(k,[]).append(v)
result =[list(x) for x in d.items()] # if you really need it as list
of lists
# if list of tuples is ok, then it´d be just:
# result = d.items()
result.sort() # if you need this list sorted by keys


 
Reply With Quote
 
Laurent Pointal
Guest
Posts: n/a
 
      02-02-2007
Neil Cerutti a écrit :
> On 2007-02-02, ardief <(E-Mail Removed)> wrote:

<zip>

> This is a job for... duhn-duhn-DAAAAH! Captain CHAOS!
>
> Er... I mean itertools.groupby.
>

<zip>
> def key_func(t):
> return t[0]


Not needed: --> from operator import itemgetter

See in the example:
http://docs.python.org/lib/itertools-example.html

So much stuff in libraries, so few we know. Thanks to doc writers,
Usenet contributors & Google search engines.
 
Reply With Quote
 
Bart Ogryczak
Guest
Posts: n/a
 
      02-02-2007
On Feb 2, 3:19 pm, Larry Bates <(E-Mail Removed)> wrote:

> l=[x for x in d.items()]


d.items() is not an iterator, you don´t need this. This code is
equivalent to l = d.items().



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can *common* struct-members of 2 different struct-types, that are thesame for the first common members, be accessed via pointer cast to either struct-type? John Reye C Programming 28 05-08-2012 12:24 AM
common elements between list of lists and lists antar2 Python 2 07-17-2008 09:19 AM
java.lang.NoSuchMethodError: wm.common.session.Common.getCustRptListFromMax Denny Java 1 05-01-2008 07:33 AM
Merging a list of similar items Henrik Goldman C++ 6 06-14-2007 01:56 AM
Counter for items in lists in lists? Charlotte Henkle Python 8 09-26-2004 04:22 AM



Advertisments