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?

asked Nov 20, 2017 at 9:48
\$\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]
Vogel612
25.5k7 gold badges59 silver badges141 bronze badges
answered Nov 20, 2017 at 11:28
\$\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)))
answered Nov 20, 2017 at 11:29
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.