Split a string of numbers into lists of even and odd integers

Having such a code

numbers = '1 2 3 4 5 6 7 8' nums = {'evens': [], 'odds': []} for number in numbers.split(' '): if int(number) % 2: nums['odds'].append(number) else: nums['evens'].append(number) 

How to do this on fewer lines?

+5
source share
6 answers

Short code is not the best code. Short code is not fast code. Short code does not support code. Now, at the same time, itโ€™s good to make your individual components concise and simple.

Here is what I will do:

 def split_odd_even(number_list): return { 'odds': filter(lambda n: (n % 2) != 0, number_list), 'evens': filter(lambda n: (n % 2) == 0, number_list) } def string_to_ints(string): return map(int, numbers.strip().split()) numbers = '1 2 3 4 5 6 7 8 9 10' nums = split_odd_even(string_to_ints(numbers)) print nums 

This gives me:

 {'odds': [1, 3, 5, 7, 9], 'evens': [2, 4, 6, 8, 10]} 

Although this code actually added a few lines in length, it became much clearer what the program does, since we applied Abstraction , and each component of the code does only one thing.

Despite the fact that we added two functions, the most noticeable part of the code left this:

 numbers = '1 2 3 4 5 6 7 8' nums = {'evens': [], 'odds': []} for number in numbers.split(' '): if int(number) % 2: nums['odds'].append(number) else: nums['evens'].append(number) 

For this:

 numbers = '1 2 3 4 5 6 7 8 9 10' nums = split_odd_even(string_to_ints(numbers)) 

And just reading these two lines, we know that numbers converted from a string to an int s list, and then we break these numbers into odd and even numbers and assign the result to nums .

To explain a couple of things that may not be familiar to everyone:

  • map() calls a function for each element in list (or tuple or another iterable) and returns a new list with the result of the function called for each element. In this case, we use it to call int() for each item in the list.

  • filter() calls a function for each element in list (or tuple or another iterable), which returns True or False for each element (well, veracity or false ) and returns a list of elements that evaluate to True when the function is called.

  • Lambda expressions ( lambda ) are like "mini-functions" that take arguments and can be created in place.

+5
source

Functional aproach:

 >>> numbers = '1 2 3 4 5 6 7 8' >>> numbers = map(int, numbers.split()) >>> nums = {'evens': filter(lambda x: x%2 == 0, numbers), 'odds': filter(lambda x: x%2 != 0, numbers)} >>> nums {'evens': [2, 4, 6, 8], 'odds': [1, 3, 5, 7]} 
+4
source

You can accomplish the same results with itertools.groupby , for example:

 >>> from itertools import groupby >>> >>> numbers = '1 2 3 4 5 6 7 8' >>> d = {'even':[], 'odd':[]} >>> mynum = [int(x) for x in numbers.strip().split()] >>> for k,g in groupby(mynum, lambda x: x % 2): if k: d['odd'].extend(g) else: d['even'].extend(g) >>> d {'even': [2, 4, 6, 8], 'odd': [1, 3, 5, 7]} 
+3
source
 numbers = '1 2 3 4 5 6 7 8' nums = {} nums["even"] = [int(i) for i in numbers.split() if int(i) % 2 == 0] nums["odd"] = [int(i) for i in numbers.split() if int(i) % 2 == 1] print(nums) 

Output:

 {'even': [2, 4, 6, 8], 'odd': [1, 3, 5, 7]} 
+1
source

If you just want to try:

 numbers = '1 2 3 4 5 6 7 8' nums = {'evens': [], 'odds': []} for number in numbers.split(' '): category = 'odds' if int(number) % 2 else 'evens' nums[category].append(number) 

But if you want to use it in production: Readable code is more important than short code

+1
source

You can do this as a single line, but I would not recommend it. Your code is ok.

 [nums['odds'].append(n) if int(n)%2 else nums['evens'].append(n) for n in numbers.split(' ')] 
0
source

All Articles