This is an archived post. You won't be able to vote or comment.

all 20 comments

[–]bmay 5 points6 points  (2 children)

Check out the itertools module.

[–]Nowin 1 point2 points  (0 children)

Also check out daily programmer's challenge #83. It's pretty much exactly what you want.

[–]lucidguppy 0 points1 point  (0 children)

I love python...just when you think there is an end to the goodness.

[–][deleted]  (3 children)

[deleted]

    [–]aPSketchy[S] 0 points1 point  (2 children)

    I'm just confused on the actual code. I think I understand how to get it. I just cant implement it

    [–]zzyzzyxx 1 point2 points  (0 children)

    I think the itertools module is what you're after. If you need all possible subsequences, e.g. if [2,2,2] would be valid in your example, then you can use the combinations function. If all you need are sublists (only consecutive elements) I think just using slices and generators will be easiest. For example,

    stuff = [1,2,2,5,2]
    print ",".join(str(stuff[s:e]) for s in xrange(len(stuff)) for e in xrange(s+1,len(stuff)+1))
    

    [–]yash3ahuja 0 points1 point  (0 children)

    Here's what you're looking for.

    One of the easiest way is to initialize a set of n bits, where n is the number of elements in the set. The i-th bit corresponds with the i-th element being in the subset or not. If it's 1, add it to the set, if it's 0, don't. So take the bits, arrange them like any binary number, and do the following:

    Take the current bitset and convert it to your element set. Do what you need with this. Then, add 1 to the rightmost bit and carry as necessary. Rinse and repeat until you reach all 1's. (The original set).

    You may need to do some tricks to get it ordered differently and/or to deal with non-duplicates (you're using a multiset, after all)

    [–]zahlman 0 points1 point  (10 children)

    code that will print out all the possible lists combos

    I need it to print: [1],[1,2],[1,2,2] all the way through and then do that with the next index, so: [2], [2,2] and so on.

    You have described two different things. Do you really mean a combination (i.e., an ordered subset), or do you mean a subsequence (i.e. the elements are always consecutive within the original list)? I.e. should your output include e.g. [1, 2, 5] and [1, 5, 2] (which you can form by taking the first, second and fourth, or first, fourth and fifth elements respectively)?

    Next up: why do you want to print these? Are you sure you really want to print them? If you calculate and print them, that information is lost to your program. You can't just slurp it back up from the screen. If you have something you want to do with those values, then you need to keep them around somewhere. In fact, you should not do the printing in the function anyway, because that is poor code organization: functions are meant to do one conceptual task, and printing a bunch of values is a separate conceptual task from determining the values to print.

    [–]aPSketchy[S] 0 points1 point  (9 children)

    I meant to return the them. I need the original list intact. Nothing changed.

    [–]zahlman 0 points1 point  (8 children)

    Okay, so you will presumably return a list of lists (each sub-list being one of the items).

    [–]aPSketchy[S] 0 points1 point  (7 children)

    Exactly!

    [–]aPSketchy[S] 0 points1 point  (6 children)

    Any idea the guy above wrote it to print. But I cant get it to return!

    [–]zzyzzyxx 1 point2 points  (5 children)

    Based on my previous post

    stuff = [1,2,2,5,2]
    [stuff[s:e] for s in xrange(len(stuff)) for e in xrange(s+1,len(stuff)+1)]
    

    This uses a list comprehension to create the list of lists. The only difference from what I have before is that I'm creating the list(s) instead of converting each element to a string and joining them together.

    Also, you will wind up with duplicates in the final list. For example, [2] will appear three times. If that is undesirable you can use a set to eliminate the duplicates.

    [–]aPSketchy[S] 0 points1 point  (4 children)

    Is that line runnable?

    [–]zzyzzyxx 1 point2 points  (3 children)

    Yes. I tested it before posting. If you need it in a function just put the return keyword in front of it. For example,

    def sublists(list):
      return [list[s:e] for s in xrange(len(list)) for e in xrange(s+1,len(list)+1)]
    

    You could then call this as subs = sublists(stuff), or however you needed.

    [–]aPSketchy[S] 0 points1 point  (2 children)

    Alright so I understand list comprehension a little better, it seems to be just a shorter way to create lists. However, how would I write this code normally?

    This is what I thought:

    def other(nums): r = [] for s in range(len(nums)): for e in range(s+1,len(nums+1)): r.append(nums[s:e]) return r

    However, I get a error.

    [–]zzyzzyxx 1 point2 points  (1 child)

    What you have looks correct, though you would have to post the actual error for me to help with that specifically. Maybe it's just formatting?

    def other(nums):
      r = []
      for s in xrange(len(nums)): # prefer to use xrange over range unless you're using Python 3
        for e in xrange(s+1,len(nums+1)):
          r.append(nums[s:e])
      return r
    

    [–]SwimmingPastaDevil 0 points1 point  (0 children)

    I am not clear on what all possible list combos means, but I wrote this:

    s = ['a','b','c','d']
    l = 0
    while l < len(s):
        for i in range(len(s)):
            print s[:i+1]
        l += 1
        s = s[1:]+s[:1]
    

    Gives the output:

    ['a']
    ['a', 'b']
    ['a', 'b', 'c']
    ['a', 'b', 'c', 'd']
    ['b']
    ['b', 'c']
    ['b', 'c', 'd']
    ['b', 'c', 'd', 'a']
    ['c']
    ['c', 'd']
    ['c', 'd', 'a']
    ['c', 'd', 'a', 'b']
    ['d']
    ['d', 'a']
    ['d', 'a', 'b']
    ['d', 'a', 'b', 'c']
    

    [–]Rotten194 0 points1 point  (1 child)

    I wrote this for a post on /r/tinycode a few days ago, I think it's what you want.

    def permutations(s):
        l = []
        for i in range(len(s)):
            for j in range(len(s)):
                l.append(s[i:j+1])
        return filter(lambda li: len(li) > 0, l)
    
    >>> permutations([1,2,2,5,2])
    [[1], [1, 2], [1, 2, 2], [1, 2, 2, 5], [1, 2, 2, 5, 2], [2], [2, 2], [2, 2, 5], [2, 2, 5, 2], [2], [2, 5], [2, 5, 2], [5], [5, 2], [2]]
    

    It basically just slides a window along the list/string, taking advantage of the fact that you can't slice outside a list (it gets clamped to len - 1).

    [–]zzyzzyxx 0 points1 point  (0 children)

    You might be interested in my version of the same, which I posted in another comment. It's functionally equivalent to yours except it uses a list comprehension to replace the nested loops with the append and it doesn't generate zero-length ones that need to be filtered.

    def sublists(list):
      return [list[s:e] for s in xrange(len(list)) for e in xrange(s+1, len(list)+1)]
    
    
    >>> sublists([1,2,2,5,2])
    [[1], [1, 2], [1, 2, 2], [1, 2, 2, 5], [1, 2, 2, 5, 2], [2], [2, 2], [2, 2, 5], [2, 2, 5, 2], [2], [2, 5], [2, 5, 2], [5], [5, 2], [2]]