1
\$\begingroup\$

I'm generating a custom combination of sub lists without using itertools.

Here's what I've come up with:

input =  [[1, 2], [2, 3], [4, 3]]
output = [[1, 2, 2, 3], [1, 2, 4, 3], [2, 3, 4, 3]]

def getList():
    a = [[1, 2], [2, 3], [4, 3]]
    return(a)

c=[]                        # output list
l = len(getList())
for i in range(l):
    for j in range(i+1,l):
        a=getList()
        a[i].extend(a[j])
        c.append(a[i])

As the extend() updates the input list, I defined a function to redefine the input. Is it a recommended practice? What could be improved here?

\$\endgroup\$
5
  • 2
    \$\begingroup\$ Why don't you want to use itertools? Because using itertools is recommended practice... \$\endgroup\$ Commented Nov 20, 2017 at 9:52
  • \$\begingroup\$ @Peilonrayz no reason as such, was just trying how to achieve without it. \$\endgroup\$ Commented Nov 20, 2017 at 9:56
  • \$\begingroup\$ @VanPeer You have a hardcoded input() in get_List(), what would happen if the input changes? \$\endgroup\$ Commented Nov 20, 2017 at 10:55
  • \$\begingroup\$ These are not all combinations of a list \$\endgroup\$ Commented Nov 20, 2017 at 11:00
  • \$\begingroup\$ @Ludisposed thanks! assuming input doesn't change. i needed only the combinations specified in the output. i didn't mention all combinations, did i? anyways, updated. \$\endgroup\$ Commented Nov 20, 2017 at 11:04

2 Answers 2

3
\$\begingroup\$
  1. Use a function.
  2. Don't mutate data you don't want to be mutated.

    Rather than using list.extend, use list.__add__. However don't use list.__iadd__, as that has the same problem as list.extend.

  3. Learn how to copy Python objects. You can use list([1, 2, 3]) to make a copy of the list. You can also use the copy library too.

  4. Don't waste memory, just yield. If you need a list use list(product(...))
def product(input):
    for i in range(len(input)):
        for j in range(i+1, len(input)):
            yield input[i] + input[j]
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Yield is better then mine, memorywise, but don't use input as a variable name. :) \$\endgroup\$ Commented Nov 20, 2017 at 11:32
  • \$\begingroup\$ @Ludisposed You could always use a generator, rather than list, comprehension. And shadowing built-ins is fine IMO. It's not like the OP's going to use the original input in the function. \$\endgroup\$ Commented Nov 20, 2017 at 11:34
  • \$\begingroup\$ I just try to avoid shadowing built ins, at all costs! Maybe just a bit paranoid :$ \$\endgroup\$ Commented Nov 20, 2017 at 11:43
  • \$\begingroup\$ @Ludisposed There are good arguments for and good against. I don't think you'll confuse input as builtins.input in a small 4 lines of code function. If however it were a 200 line function I'd whole heartedly agree. I do admit it's not that great a variable name, but we don't have context to improve on that. \$\endgroup\$ Commented Nov 20, 2017 at 11:47
4
\$\begingroup\$

What could be improved here?

@thnx Peilonrayz, a generator expression will work better on large inputs

  1. Use a nested generator expression.
  2. DON'T hardcode variables, this will make your code very static.
  3. Make a function, to accept different variables.

def custom_combo(L):
    return (L[i] + L[j] for i in range(len(L)) for j in range(i+1, len(L)))

if __name__ == '__main__':
    a = [[1, 2], [2, 3], [4, 3]]
    print(list(custom_combo(a)))
\$\endgroup\$
0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.