1

Basically, I have a list and I want to perform multiple functions on it at once. For example,

List = [1,2,3,4,5]
List.extend([1,2,3,4,5]).sort().reverse()

I would like the result to be [5,5,4,4,3,3,2,2,1,1].

I haven't used Python in a while, but I know I've done something like this before. Is it something simple I'm missing or what?

It has to all be on one line by the way.

David Robinson
  • 77,383
  • 16
  • 167
  • 187
Stephen Roda
  • 859
  • 6
  • 13
  • 20
  • 5
    Why does it have to be all on one line? – BrenBarn Aug 29 '12 at 04:37
  • Trust me, if the requirements weren't that it had to be all on one line this would be much easier. But I guess it's about learning to condense code. – Stephen Roda Aug 29 '12 at 04:39
  • If you are learning Python, you should learn that sometimes you need uncondense code to emphasize readability over terseness. – BrenBarn Aug 29 '12 at 04:41
  • if you want to really piss some people off, use semicolons, and chain the commands lol – notbad.jpeg Aug 29 '12 at 04:42
  • I agree that learning to condense the code before actually knowing how it works is kind of pointless. But it's a tradeoff; getting higher grades or actually learning the material. I know that learning the material is more important in the long run, but grades are also important. Today's educational system I guess :/ – Stephen Roda Aug 29 '12 at 04:45
  • 3
    @BrenBarn, obviously it's faster if is all on one line :p – John La Rooy Aug 29 '12 at 04:52
  • Oh, this is a homework problem. Geez. – BrenBarn Aug 29 '12 at 04:55
  • @BrenBarn, I'm not asking you to do it, I just thought there was a way to use multiple functions on one line. Thanks for the input though.. – Stephen Roda Aug 29 '12 at 05:09

6 Answers6

7

Most Python methods that mutate a container in-place return None

However your example can easily be handled in one line

L = [1,2,3,4,5]
L = sorted(L+[1,2,3,4,5], reverse=True)

Keeping in the spirit of the challenge, it's not hard to chain the operations (because they always return None)

>>> L = [1, 2, 3, 4, 5]
>>> L.extend([1,2,3,4,5]) or L.sort() or L.reverse() or L
[5, 5, 4, 4, 3, 3, 2, 2, 1, 1]

Here's another way

>>> L = [1, 2, 3, 4, 5]
>>> (L.extend([1,2,3,4,5]), L.sort(), L.reverse()) and L
[5, 5, 4, 4, 3, 3, 2, 2, 1, 1]

And you can let your imagination run wild

>>> L = [1, 2, 3, 4, 5]
>>> max(L.extend([1,2,3,4,5]), L.sort(), L.reverse(), L) # Python2.x only
[5, 5, 4, 4, 3, 3, 2, 2, 1, 1]
Community
  • 1
  • 1
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
  • 3
    These are pretty *ugly* tricks producing unreadable code for non-Python gurus and therefore deserves a downvote...no trickery please –  Aug 29 '12 at 05:18
  • I actually like this answer, but I'm quite new to Python. Are the commas ugly tricks too? I think they're pretty useful. – Stephen Roda Aug 29 '12 at 05:28
  • I agree with @esaelPsnoroMoN: Do as you want at home, but don't advertise it. -1. – Pierre GM Aug 29 '12 at 08:59
4

You cannot chain the above operations since they are performed in-place. As alternatives, use sorted() and reversed().

Ry-
  • 218,210
  • 55
  • 464
  • 476
  • And why exactly in-place operations prevent chaining? If `sort` and `reverse` had returned reference to the original list, the example in the OP would be possible. – rkhayrov Aug 29 '12 at 04:41
  • Why do you want to argue? As said: the methods are *in-place* and there result is None. So it is obviously that you can not chain *POINT* –  Aug 29 '12 at 04:42
  • 1
    @esaelPsnoroMoN Because it's precision that matters. The lack of return value prevents chaining, not in-place operation. – rkhayrov Aug 29 '12 at 04:43
  • 1
    @rkhayrov, The are detailed reasons for the decision on the Python dev list some time last century – John La Rooy Aug 29 '12 at 04:45
  • 2
    @esaelPsnoroMoN I find your comments not constructive, and borderline offensive. If you haven't noticed, I am not an OP. I haven't suggested that Python does this wrong. I've only pointed out that your answer contains logical fallacy. – rkhayrov Aug 29 '12 at 05:18
4

How about:

>>> l = [1,2,3,4,5]*2
>>> l.sort(reverse=True)
>>> l
[5, 5, 4, 4, 3, 3, 2, 2, 1, 1]

Or even shorter:

>>> sorted([1,2,3,4,5]*2,reverse=True)
[5, 5, 4, 4, 3, 3, 2, 2, 1, 1]
Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
1

Each of those functions acts on the list in-place, returning None and not the modified list. You'd have to do something like

l = [1,2,3,4,5]
l = reversed(sorted(l + [1,2,3,4,5]))
chepner
  • 497,756
  • 71
  • 530
  • 681
1

Not perfect but interesting..

class chain():
    def __init__(self, my_object):
        self.o = my_object

    def __getattr__(self, attr):
        x = getattr(self.o, attr)
        if hasattr(x, '__call__'):
            method = x
            return lambda *args: self if method(*args) is None else method(*args)
        else:
            prop = x
            return prop

list_ = chain([1, 2, 3, 0])
print list_.extend([9,5]).sort().reverse()
Rusty Rob
  • 16,489
  • 8
  • 100
  • 116
0

The functions extend, sort and reverse doesn't return list but change the list on which they are called. Chaining relies on a fact that previous function returns some value and works on it.

E.g. s="abc" then you can do s.upper().lower() as .upper() return a new string in uppercase (ans same for .lower()).

Rohan
  • 52,392
  • 12
  • 90
  • 87