Searching and manipulating lists of tuples

bruno at modulix onurb at xiludom.gro
Mon Jun 12 18:27:11 CEST 2006


MTD wrote:
> Hello,
> 
> I'm wondering if there's a quick way of resolving this problem.
> 
> In a program, I have a list of tuples of form (str,int), where int is a
> count of how often str occurs
> 
> e.g. L = [ ("X",1),("Y",2)] would mean "X" occurs once and "Y" occurs
> twice
> 
> If I am given a string, I want to search L to see if it occurs already.
> If it does, I find the corresponding tuple and increment the integer
> part. If not, I append the new element with int = 1.
> 
> e.g.
> 
> algorithm(L, "X") would produce output L = [("X",2),("Y",2)]
> algorithm(L,"Z") would produce L = [("X",1),("Y",2),("Z",1)]

if you don't mind about ordering:

def algorithm(items, target):
  d = dict(items)
  try:
    d[target] += 1
  except KeyError:
    d[target] = 1
  items[:] = d.items()

Now it would probably be better to directly use a dict instead of a list
of tuples if possible...

> I tried to create an algorithm of the following form:
> 
>>>>def algorith(list,str):

Using 'list' and 'str' as identifiers will shadow the eponym builtin
types in this function. This may or may not be a problem here, but it's
usually better to avoid doing so.

> ... 	flag = True
> ... 	for l in list:
> ... 		if l[0] == str:
> ... 			l[1] += 1
tuples are immutable. Hence the exception.

> ... 			flag = False
'break'ing here would avoid useless iterations. And also allow the use
of the 'else' clause of the for loop, si you don't need a flag.
> ... 	if flag:
> ... 		list.append((str,1))


> ...

While there are pretty good reasons to favor the dict-based solution
(unless you really insist on having sub-optimal code of course !-), the
following is a somewhat more pythonic rewrite of your original code:

def algogo(alist, astring):
  for i, (name, count) in enumerate(alist):
    if name == astring:
      alist[i] = (name, count+1)
      break
  else:
    alist.append( (astring, 1) )


(snip)
-- 
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"



More information about the Python-list mailing list