How to store some elements from a list into another
Jussi Piitulainen
jussi.piitulainen at helsinki.fi
Tue Jun 13 03:48:53 EDT 2017
breamoreboy at gmail.com writes:
> On Monday, June 12, 2017 at 7:33:03 PM UTC+1, José Manuel Suárez Sierra wrote:
>> Hello,
>> I am stuck with a (perhaps) easy problem, I hope someone can help me:
>>
>> My problem is:
>> I have a list of lists like this one:
>> [[55, 56, 57, 58, 83, 84, 85, 86, 89, 90, 91, 92, 107, 108, 109, 110,
>> 111, 117, 118, 119, 120, 128, 129, 130, 131, 135, 136, 137, 138, 184,
>> 185, 186, 187, 216, 217, 218, 219, 232, 233, 234, 235, 236, 237, 238,
>> 267, 268, 269, 270, 272, 273, 274, 275], [2, 3, 4, 5, 9, 10, 11, 12,
>> 21, 22, 23, 24, 29, 30, 31, 32, 56, 57, 58, 59, 65, 66, 67, 68, 74,
>> 75, 76, 77, 78, 89, 90, 91, 92, 98, 99, 100, 101, 102, 125, 126, 127,
>> 128, 131, 132, 133, 134, 135]]
>>
>> And what I want is to store some of these datum into another list
>> according to the next conditions:
>>
>> 1. I just want to store data if these values are consecutive (four in
>> four), for instance, for first element I would like to store into the
>> new list: [[[55,58],[83,86],....[n,n+3]]] and so on.
>>
>> I tried something like this:
>>
>> x=0
>> y=0
>> while list6[x][y] == list6[x][y+1]-1 and list6[x][y] == list6[x][y+1]-2 and list6[x][y] == list6[x][y+1]-3 or list6[x][0]:
>>
>> list7.append(list6[x][y])
>> list7.append(list6[x][y+3])
>> y = y+1
>> if (list6[x][y])%(list6[x][len(list6[x])-1]) == 0:
>> x= x+1
>>
>> if len(list6[x]) == x and len(list6[x][y]) == y:
>> break
>>
>>
>> It does not work
>>
>> I appreciate your help
>> Thank you
>
> Perhaps use the recipe for consecutive numbers from here
> https://docs.python.org/2.6/library/itertools.html#examples It will
> have to be modified for Python 3, I'll leave that as an exercise.
What a clever idea. Pity it's gone in newer documentation. (By the "it"
in the previous sentence I refer only to the idea of grouping by the
difference to the index in the original sequence, and by "gone" only to
the fact that I didn't see this example at the corresponding location
for Python 3.6, which I found by replacing the 2 in the URL with 3.
Perhaps the idea is preserved somewhere else?)
Anyway, I've adapted it to Python 3, and to an analysis of the problem
at hand - mainly the problem that the OP finds themselves _stuck_ with
their spec and their code, as quoted above. Hope it helps.
What follows, follows.
# The big idea is to define (auxiliary) functions. It's not an
# advanced idea. It's the most basic of all ideas. The experience of
# being stuck comes from trying to see the whole problem at once.
# Ok, familiary with standard ways of viewing things helps. But that
# is just the flip side of breaking problems into manageable parts:
# past experience suggests that some kinds of parts are more useful,
# more composable into a solution, so in standard libraries.
# One subproblem is to group just one list of numbers, then it is easy
# to group every list in a list of such lists. But another subproblem
# is to deal with one group of numbers. There seem to be two concerns:
# a group should consist of consecutive numbers, and a group should
# consist of four numbers - the latter at least is easy enough if the
# group is stored as a list, but what should be done if there are five
# or seven numbers? No idea, but that can be clarified later once the
# components of a solution are untangled into their own functions.
# The battle cry is: Use def!
import itertools as it
import operator as op
def applied(f):
'''Reification of that asterisk - like a really advanced
computer-sciency kind of thing. But see no lambda!'''
def F(args): return f(*args)
return F
def consequences(data):
'''Lists of consecutive datami, clever idea adapted from
https://docs.python.org/2.6/library/itertools.html#examples'''
for k, group in it.groupby(enumerate(data), applied(op.sub)):
yield [datum for index, datum in group]
def isfourlong(sequence):
'''True if sequence is of length 4.'''
return len(sequence) == 4
def ends(sequences):
'''Collect the endpoints of sequences in a list of 2-lists.'''
return [[sequence[0], sequence[-1]] for sequence in sequences]
data = [[55, 56, 57, 58, 83, 84, 85, 86, 89, 90, 91, 92, 107, 108,
109, 110, 111, 117, 118, 119, 120, 128, 129, 130, 131, 135,
136, 137, 138, 184, 185, 186, 187, 216, 217, 218, 219, 232,
233, 234, 235, 236, 237, 238, 267, 268, 269, 270, 272, 273,
274, 275],
[2, 3, 4, 5, 9, 10, 11, 12, 21, 22, 23, 24, 29, 30, 31, 32,
56, 57, 58, 59, 65, 66, 67, 68, 74, 75, 76, 77, 78, 89, 90,
91, 92, 98, 99, 100, 101, 102, 125, 126, 127, 128, 131, 132,
133, 134, 135]]
def testrun():
'''See how many variations can be composed out of the few auxiliary
functions - the problem becomes tame, or at least a bit tamer.
This kind of ad-hoc test suite is very useful, during development,
when at all in doubt.'''
print('groups in both lists:')
print(list(consequences(data[0])))
print(list(consequences(data[1])))
# note the calls to list() - consequences() returns an opaque
# generator object that can be drained into a list when needed;
# filter objects below are similarly opaque and drainable - define
# an auxiliary that returns a list instead if that feels scary -
# Don't Panic!
print()
print('groups of four in both lists:')
print(list(filter(isfourlong, consequences(data[0]))))
print(list(filter(isfourlong, consequences(data[1]))))
print()
print('ends of all groups in both lists:')
print(ends(consequences(data[0])))
print(ends(consequences(data[1])))
print()
print('ends of groups of four in both lists:')
print(ends(filter(isfourlong, consequences(data[0]))))
print(ends(filter(isfourlong, consequences(data[1]))))
print()
print('lists of ends of all groups:')
print([ends(consequences(datami)) for datami in data])
print()
print('lists of ends of groups of four:')
print([ends(filter(isfourlong, consequences(datami)))
for datami in data])
if __name__ == '__main__':
# inside the above condition, these commands are executed when the
# script is executed but not when it is imported as a library, so
# it is easy to run the test from the shell and easy to import the
# definitions into an interactive session
testrun()
More information about the Python-list
mailing list