I am trying to loop through a list but at the same time make reference to the items before so i can compare.
This is my code:
list1=[(1,'a','hii'),(2,'a','byee'),(3,'a','yoo'),(4,'b','laa'),(5,'a','mehh')]
I want to loop through my list1 tuples such that if the second value in the tuple is the same value as the second value in the tuple before (both =='a'), then concat the third item in the tuple.
output i want:
list2=[('a','hii,byee,yoo'),('b','laa'),('a','mehh')]
What i have tried:
for item in list1:
for item2 in list2:
if item[0]==(item2[0]-1) and item[1]==item2[1]:
print item[2]+','+item2[2]
elif item[0] != item2[0]-1:
continue
elif item[0]==(item2[0]-1) and item[1] != item2[1]:
print item[2]
wrong output
hii,byee
byee,yoo
yoo
laa
From the first 2 output, it seems like the loop only looks at the preceding value but not at say 2 or more value preceding. Hence it only joined 2 words together and not 3 which it should have. The output also ends up having repeats.
How do i get around this?
I was making this WAY harder than it needed to be
def combine(inval):
outval = [inval[0]]
for item in inval[1:]:
if item[0] == outval[-1][0] + 1 and item[1] == outval[-1][1]:
outval[-1] = (item[0], item[1], ",".join([outval[-1][2], item[2]]))
continue
outval.append(item)
return [(item[1], item[2]) for item in outval]
And to test it...
list1 = [(1,'a','hii'),(2,'a','byee'),(3,'a','yoo'),(4,'b','laa'),(5,'a','mehh')]
list2 = [(1,'a','hii'),(3,'a','byee'),(4,'a','yoo'),(5,'b','laa'),(6,'a','mehh')]
list3 = [(1,'a','hoo'),(3,'a','byee'),(5,'a','yoo'),(6,'a','laa'),(7,'a','mehh'),(9, 'b', 'nope')]
for l in (list1, list2, list3):
print "IN:", l
print "OUT:", combine(l)
print
OUTPUT
IN: [(1, 'a', 'hii'), (2, 'a', 'byee'), (3, 'a', 'yoo'), (4, 'b', 'laa'), (5, 'a', 'mehh')]
OUT: [('a', 'hii,byee,yoo'), ('b', 'laa'), ('a', 'mehh')]
IN: [(1, 'a', 'hii'), (3, 'a', 'byee'), (4, 'a', 'yoo'), (5, 'b', 'laa'), (6, 'a', 'mehh')]
OUT: [('a', 'hii'), ('a', 'byee,yoo'), ('b', 'laa'), ('a', 'mehh')]
IN: [(1, 'a', 'hoo'), (3, 'a', 'byee'), (5, 'a', 'yoo'), (6, 'a', 'laa'), (7, 'a', 'mehh'), (9, 'b', 'nope')]
OUT: [('a', 'hoo'), ('a', 'byee'), ('a', 'yoo,laa,mehh'), ('b', 'nope')]
This takes care of both guaranteeing sequential numbers at the 0th-index as well as equal values at the 1st-index.
Edit: I've updated the algorithm according to the requirements. You can group all tuples with the same key by calling group(values, sort=True) or only group adjacent tuples with the same key by calling group(values). This algorithm also gathers all elements after the key for the final tuple instead of only grabbing the third element.
GroupBy does this pretty well. You can group the values by the second element in the tuple. Then for each group, grab all of the third elements in the group and join them into one string:
import itertools
def keySelector(tup):
return tup[1]
def group(values, sort=False):
"""
Group tuples by their second element and return a list of
tuples (a, b) where a is the second element and b is the
aggregated string containing all of the remaining contents
of the tuple.
If sort=True, sort the tuples before grouping. This will
group all tuples with the same key. Otherwise, only adjacent
tuples wth the same key will be grouped.
"""
if sort:
values.sort(key=keySelector)
grouped = itertools.groupby(values, key=keySelector)
result = []
for k, group in grouped:
# For each element in the group, grab the remaining contents of the tuple
allContents = []
for tup in group:
# Convert tuple to list, grab everything after the second item
contents = list(tup)[2:]
allContents.extend(contents)
# Concatenate everything into one string
aggregatedString = ','.join(allContents)
# Add to results
result.append((k, aggregatedString))
return result
vals = [(1,'a','hii','abc','def'),
(2,'a','byee'),
(3,'a','yoo'),
(4,'b','laa'),
(5,'a','mehh','ghi','jkl')]
print(group(vals, sort=True))
Output:
[('a', 'hii,abc,def,byee,yoo,mehh,ghi,jkl'), ('b', 'laa')]
Shortened version with list comprehensions:
def getGroupContents(tuples):
return ','.join(item for tup in tuples for item in list(tup)[2:])
def group(values, sort=False):
if sort:
values.sort(key=keySelector)
grouped = itertools.groupby(values, key=keySelector)
return [(k, getGroupContents(tuples)) for k, tuples in grouped]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With