18

I have two lists like this:

monkey = ['2\n', '4\n', '10\n']

banana = ['18\n', '16\n', '120\n']

What I want to do with these two list is make a third list, let's call it bananasplit.

I have to strip away ' \n', leaving only values and then make a formula which divides into:

bananasplit[0] = banana[0]/monkey[0]

bananasplit[1] = banana[1]/monkey[1] etc

I experimented with while-loop but can't get it right. Here is what I did:

bananasplit = 3*[None]

i = 0

while i <= 2:

    [int(i) for i in monkey]

    [int(i) for i in banana]

    bananasplit[i] = banana[i]/monkey[i]

    i += 1

How would you demolish this minor problem?

RasmusJ
  • 396
  • 1
  • 2
  • 10

4 Answers4

29

The following will do it:

>>> bananasplit = [int(b) / int(m) for b,m in zip(banana, monkey)]
>>> print(bananasplit)
[9, 4, 12]

As far as your original code goes, the main issue is that the following are effectively no-ops:

[int(i) for i in monkey]
[int(i) for i in banana]

To turn them into something useful, you would need to assign the results somewhere, e.g.:

monkey = [int(i) for i in monkey]
banana = [int(i) for i in banana]

Finally, it is worth noting that, depending on Python version, dividing one integer by another using / either truncates the result or returns a floating-point result. See In Python 2, what is the difference between '/' and '//' when used for division?

Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • 1
    You're example is nice and to the point, but one remark: you don't need the `strip()`, as `int()` doesn't care about it. – Thorsten Kranz Jan 21 '13 at 08:26
  • I have `q = [[7,2,3],[4,5,6]]` and `r=[[6,1,2],[3,4,5]]`. I need to divide the corresponding elements. `B= [[float(j)/float(i) for j in q] for i in r]`. However, I keep getting an error : TypeError: float() argument must be a string or a number. I have imported division from future. Any suggestions? – Rspacer Oct 11 '16 at 04:26
  • @Biotechgeek Since q and r are nested lists (each element of the list is a list), your "j" and "i" are lists, not values. To do what I think you want to do, you have to do something like this: `B = [[float(jj)/float(ii) for jj, ii in zip(i, j)] for i,j in zip(q,r)]`. This will produce a list of two lists which are three elements each: `[[1.1666666666666667, 2.0, 1.5], [1.3333333333333333, 1.25, 1.2]]`. – Arthur Dent Oct 19 '17 at 16:07
2

Try something like this.

bananasplit = [x/y for x, y in zip(map(int, banana), map(int, monkey))]

If you want the float result (in python 2.x), you can change the ints to be float, or from __future__ import division

DanielB
  • 2,798
  • 1
  • 19
  • 29
  • +1 for being so succinct, -1 for being so succinct, and without any comments. Do you think the poster will be able to follow? – 9000 Jan 21 '13 at 08:28
  • 1
    @9000 By the time I'd posted then come back to add detail NPE's answer already covered it all - didn't feel the need to repeat it all. If someone misses that answer I'll leave it as an exercise to be figured out :P – DanielB Jan 21 '13 at 08:32
  • 1
    `map`ping on `int` before the `zip` is missing half the expressive power of the list comprehension. If you want to do things that way, you might as well go all out with `map(int.__div__, map(int, banana), map(int, monkey))` or something. At least then you're leveraging the implicit zipping built in to `map`. :P Or, for that matter, `map(lambda b, m: int(b) / int(m), banana, monkey)`. – Karl Knechtel Jan 21 '13 at 08:52
  • @DanielB: I see. I only wanted to notice that, given the poster's knowledge level obvious from the question, a magical incantation (or what look like one for an untrained eye) might be less helpful than an explanation how things work. Can you imagine adding to your codebase a fragment that works but you don't know why and how? – 9000 Jan 21 '13 at 17:31
1

List iteration and map function gets you there very quickly.

>>> monkey = ['2\n', '4\n', '10\n']

>>> banana = ['18\n', '16\n', '120\n']

>>> monkey = [ float(m.strip()) for m in monkey]

>>> banana = [ float(m.strip()) for m in banana]

>>> def div(a,b):

...     return a/b

... 

>>> map(div, banana, monkey)

[9.0, 4.0, 12.0]

>>> 
Supreet Sethi
  • 1,780
  • 14
  • 24
0

A list comprehension, like [an_expression for some_variable in some_sequence] returns you a new list. Your example just drops these results.

# remove trailing whitespace and convert strings to numbers
monkey_numbers = [int(item.strip()) for item in monkey]
banana_numbers = [int(item.strip()) for item in banana]

# a traditional loop
bananasplit = [] # an empty list
for i in range(len(banana_numbers)):
  # make bananasplit longer on each iteration
  bananasplit.append(banana_numbers[i] / monkey_numbers[i])

Then, you can use a list comprehension instead of a loop since your expression is so simple. You will need zip function that takes two lists and makes a list of pairs.

# divide in one statement
bananasplit = [
  banana_portion / monkey_bunch 
  for (banana_portion, monkey_bunch) in 
  zip(banana_numbers, monkey_numbers)
]

Of course, you are free to use shorter identifiers; I used long names to make their roles easier to understand.

9000
  • 39,899
  • 9
  • 66
  • 104