Slicing iterables in sub-generators without loosing elements
88888 Dihedral
dihedral88888 at googlemail.com
Sun Sep 30 20:58:39 EDT 2012
On Sunday, September 30, 2012 12:15:57 AM UTC+8, Thomas Bach wrote:
> Hi,
>
>
>
> say we have the following:
>
>
>
> >>> data = [('foo', 1), ('foo', 2), ('bar', 3), ('bar', 2)]
>
>
>
> is there a way to code a function iter_in_blocks such that
>
>
>
> >>> result = [ list(block) for block in iter_in_blocks(data) ]
>
>
>
> evaluates to
>
>
>
> >>> result = [ [('foo', 1), ('foo', 2)], [('bar', 3), ('bar', 2)] ]
>
>
>
> by _only_ _iterating_ over the list (caching all the elements sharing
>
> the same first element doesn't count)?
>
>
>
> I came up with the following
>
>
>
> def iter_in_blocks(iterable):
>
> my_iter = iter(iterable)
>
> while True:
>
> first = next(my_iter)
>
> pred = lambda entry: entry[0] == first[0]
>
> def block_iter():
>
> yield first
>
> for entry in itertools.takewhile(pred, my_iter):
>
> yield entry
>
> yield block_iter()
>
>
>
> which does not work as itertools.takewhile consumes the first entry
>
> not fulfilling the pred.
>
>
>
> I currently have the intuition that the problem is not solvable
>
> without using e.g. a global to pass something back to iter_in_blocks
>
> from block_iter. Any other suggestions?
>
>
>
> Regards,
>
> Thomas Bach.
Your question seems vague to me. If you know you are storing
only immutable tuples in a list, then the way to iterate is simple.
For example:
data = [('foo', 1), ('foo', 2), ('bar', 3), ('bar', 2)]
# all tuples
for item in data:
x1=item[0] # first entry in each tuple
x2=item[1]
print x1, x2 # or use yield in a function to iterate
More information about the Python-list
mailing list