-3

I based my original function on this post, this post, and this post. But it's not working. The main gotcha I'm getting is that even when I put tuple(c) in Example Two, I still get a list back.

I have two examples, one with nested tuples (the way it should be) and one with nested tuples in a list so that you can easily see the extra enclosure since there are too many parenthesis with nested tuples.

def example_one():
    list_one = ((1, 2), (3, 4), (5, 6), (7, 8), (9, 10))
    list_two = []
    print "List One: " + str(list_one)      
    for i in range(0, 5):
        c_tuple = tuple(c for c in itertools.combinations(list_one[:i], i))
        list_two.append(c_tuple)
    list_two = tuple(list_two)
    print "List Two: " + str(list_two)

Outputs:

List One: ((1, 2), (3, 4), (5, 6), (7, 8), (9, 10))
List Two: (((),), (((1, 2),),), (((1, 2), (3, 4)),), (((1, 2), (3, 4), (5, 6)),), (((1, 2), (3, 4), (5, 6), (7, 8)),))

and

def example_two():
    list_one = ((1, 2), (3, 4), (5, 6), (7, 8), (9, 10))
    list_two = []
    print "List One: " + str(list_one)      
    for i in range(0, 5):
       c_tuple = [tuple(c) for c in itertools.combinations(list_one[:i], i)]
       list_two.append(c_tuple)
    list_two = tuple(list_two)
    print "List Two: " + str(list_two)

Outputs:

List One: ((1, 2), (3, 4), (5, 6), (7, 8), (9, 10))
List Two: ([()], [((1, 2),)], [((1, 2), (3, 4))], [((1, 2), (3, 4), (5, 6))], [((1, 2), (3, 4), (5, 6), (7, 8))])

In the second example, the parenthesis represent the tuple in example one that I am trying to eliminate. In fact, to be honest, I am not sure if it is that tuple or the one inside that. Whichever one is being added unnecessarily I guess.

DESIRED OUTPUT:

List One: ((1, 2), (3, 4), (5, 6), (7, 8), (9, 10))
List Two: ((()), ((1, 2)), ((1, 2), (3, 4)), ((1, 2), (3, 4), (5, 6)), ((1, 2), (3, 4), (5, 6), (7, 8)))
Community
  • 1
  • 1
user58446
  • 269
  • 1
  • 3
  • 17

3 Answers3

1

Like you have mentioned, you could avoid doing [tuple(c) for c in iterable] and just do the following. (Also simplified / minified a lot of things)

>>> list_one = ((1, 2), (3, 4), (5, 6), (7, 8), (9, 10))
>>> list_two = []
>>> print "List One: ", list_one
List One:  ((1, 2), (3, 4), (5, 6), (7, 8), (9, 10))
>>> list_two = tuple(
...     c for i in range(0, 5)
...     for c in itertools.combinations(list_one[:i], i)
... )
>>> print "List Two: ", list_two
List Two:  ((), ((1, 2),), ((1, 2), (3, 4)), ((1, 2), (3, 4), (5, 6)), ((1, 2), (3, 4), (5, 6), (7, 8)))
shad0w_wa1k3r
  • 12,955
  • 8
  • 67
  • 90
  • No, its not the empty tuple at the beginning I am trying to get rid of: that is supposed to be there. I am trying to get rid of the extra tuple wrapping the second wrapped tuple. For example: (()), ((1, 2)), ((2, 3), (3, 4))... is good. I am getting: ((())), (((1, 2))), (((2, 3), (3, 4)))... – user58446 Mar 23 '17 at 07:20
  • I believe the problem would have originally been avoided if [tuple(c) for c in iterable] returned tuple(c) instead of list(c). Or else I am reading the output wrong. – user58446 Mar 23 '17 at 07:21
  • Yes, updating my answer. – shad0w_wa1k3r Mar 23 '17 at 07:22
  • Placed desired output in question post. It was unclear. – user58446 Mar 23 '17 at 07:23
  • In your example output, the second element (1, 2) still has 3 sets of parenthesis around it. So does the first. Should only be two sets. But I like your other refactor. – user58446 Mar 23 '17 at 07:35
  • Oh okay, updated my answer. You need to note that nested comprehensions follow the order of the `for` loops as going deeper when you go left to right. – shad0w_wa1k3r Mar 23 '17 at 07:44
  • Yes, I think this one works. I need to work with it a little more to make sure, but can you explain what you did? I don't know if I'd have thought of it, and I don't think this is a trivial case. – user58446 Mar 23 '17 at 15:50
  • I rearranged the list comprehension to the desired output. I followed what a normal loop would have looked like & transformed it to a comprehension. You can do the reverse to get a hint, but I'd suggest attempting it yourself first :) – shad0w_wa1k3r Mar 23 '17 at 19:15
0

In your second example you are adding nested tuples in to a list, appending those lists into a big list and finally converting that big list to a tuple. That's why you are getting the lists in your tuple

The line which is creating a lists is

c_tuple = [tuple(c) for c in itertools.combinations(list_one[:i], i)]

if you have the square braces, it will return a list only

NMN
  • 372
  • 3
  • 16
0

You have to use extend instead of append while adding c_tuple to list_two!

To get a clear picture on the difference between two, Take a look at this

import itertools

def example_two():
    list_one = ((1, 2), (3, 4), (5, 6), (7, 8), (9, 10))
    list_two = []
    print "List One: " + str(list_one)      
    for i in range(0, 5):
       c_tuple = [tuple(c) for c in itertools.combinations(list_one[:i], i)]
       list_two.extend(c_tuple) #here instead of append use extend!
    list_two = tuple(list_two)
    print "List Two: " + str(list_two)

Output:

List One: ((1, 2), (3, 4), (5, 6), (7, 8), (9, 10))
List Two: ((), ((1, 2),), ((1, 2), (3, 4)), ((1, 2), (3, 4), (5, 6)), ((1, 2), (3, 4), (5, 6), (7, 8)))

Hope it helps!

Community
  • 1
  • 1
Keerthana Prabhakaran
  • 3,766
  • 1
  • 13
  • 23