Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Eela6
May 25, 2007
Shredded Hen

pangstrom posted:

Probably sounds like faux outrage but I'm really just curious: is starting bullet lists for human consumption with element zero something programmers routinely do?

I do it, because otherwise my mind will snap back to one-based indexing and my code will start breaking on me. Years of MATLAB left permanent damage.

Adbot
ADBOT LOVES YOU

Eela6
May 25, 2007
Shredded Hen

Cocoa Crispies posted:

In Ruby and Elixir, I got in the habit of chaining up operations on collections, with chained Enumerable methods in the former and pipes in the latter:
code:
jobs
|> Stream.map(&identify_most_recent)
|> Stream.reject(&is_nil)
|> Stream.map(&Build.from_job)
|> Stream.filter(fn(build) -> Build.expected_performer(build))
I've got a hang on how the map function and list comprehensions work in isolation, but is there a way to both keep these steps in separate lines for readability but not have to put each step in a separate variable?

You can chain comprehensions, re-using the same variable name(s) each time. The interpreter will know what you mean. Chaining generator comprehensions in this way is considered idiomatic python, and is fast & efficient!

IN
Python code:

words = "The quick brown fox jumped over the lazy dog".split()
words = (word for word in words if 'o' in word or 'e' in word) # generator comprehension: not evaluated yet!
words = (word[::-1] for word in words) #same here
print(list(words)) #finally evaluated here
OUT
code:
['ehT', 'nworb', 'xof', 'depmuj', 'revo', 'eht', 'god']
You could also use map and filter for this for more traditional functional programming. I prefer comprehensions, especially because you can avoid declaring so many lambdas, but the decision is up to you.

Python code:
words = "The quick brown fox jumped over the lazy dog".split()
words = filter(lambda word: 'o' in word or 'e' in word, words)
words = map(lambda word: word[::-1], words)
print(list(words)) #finally evaluated here

Eela6 fucked around with this message at 06:34 on Jun 6, 2017

Eela6
May 25, 2007
Shredded Hen

Malcolm XML posted:

fluent python owns

:agreed:

Eela6
May 25, 2007
Shredded Hen

:tviv:

Eela6
May 25, 2007
Shredded Hen

Thermopyle posted:

This thread has always been open to beginners. The poster who has been asking questions is obviously a beginner. Floating point stuff obviously is weird to beginners.

Numerical Analysis is not an easy subject and it frustrates me when people pretend it's simple & intuitive.

Eela6
May 25, 2007
Shredded Hen

Nippashish posted:

In the vast (vast) majority of cases they are in fact very simple and intuitive. It's extremely rare to need a mental model of floating point that is more sophisticated than "they're like real numbers except that they get funny when they're really big or really small" even if you work with them every day.

Python code:
In [8]: .3/3 == .1
Out[8]: False

Eela6
May 25, 2007
Shredded Hen

Nippashish posted:

That's why I'm suggesting a very simple mental model that is intuitive and also sufficient for even non-beginners. Teaching people that floating point numbers are dark and spooky and complicated isn't very productive, because very few people need to care about that level of detail.

I'm responding to "Numerical Analysis is not an easy subject and it frustrates me when people pretend it's simple & intuitive" by pointing out that for most practical purposes it can be made to be exactly that.

I'm not against teaching people rules of thumb, but pretending that they're more than just rules of thumb is dumb. An important part of being a professional is knowing the limits of your knowledge.

Eela6
May 25, 2007
Shredded Hen
As a note, the fact that approximate equality is often useful when comparing floats comes up often enough that isclose was added to the math and cmath modules in Python 3.5.

Python code:
In [13]: from math import isclose
    ...: isclose(.3/3, .1)
    ...:
Out[13]: True

Eela6
May 25, 2007
Shredded Hen
By the way, you shouldn't store currency in floats.

Eela6
May 25, 2007
Shredded Hen

baka kaba posted:

I mean yeah, the other extreme is the 'you can't trust floats' one, where people pretend they're full of gremlins adding random inaccuracy when your back is turned, but that's not the same as being wary and knowing what does and doesn't work

You can't trust them, though. They seem to stay still when your back is turned, but I can feel the heat of their hideous eyes. Watching. Waiting. Ready to pounce. They may not be Real, but their claws are sharp enough.

funny Star Wars parody posted:

I'm assuming that you should use doubles but please expand on this

Stack Overflow has a reasonable answer. You should not use doubles - you should use Decimals. To quote the relevant part:

Zneak from Stack Overflow posted:

The problem with floats and doubles is that the vast majority of money-like numbers don't have an exact representation as a integer times a power of two. In fact, the only fractions of a hundred between 0/100 and 100/100 (which are significant when dealing with money because they're integer cents) that can be represented exactly as an IEEE-754 binary floating-point number are 0, 0.25, 0.5, 0.75 and 1. All the others are off by a small amount.

Representing money as a double or float will probably look good at first as the software rounds off the tiny errors, but as you perform more additions, subtractions, multiplications and divisions on inexact numbers, you'll lose more and more precision as the errors add up. This makes floats and doubles inadequate for dealing with money, where perfect accuracy for multiples of base 10 powers is required.

I mostly posted the point about currency to tweak Nippanish's nose, but I'm actually glad I did. More people should know.

Eela6 fucked around with this message at 21:19 on Jun 11, 2017

Eela6
May 25, 2007
Shredded Hen
I am on that side. That said, I learned how to program in a numerical analysis class, so I recognize I am a bit of an outlier here.

Eela6
May 25, 2007
Shredded Hen

Thermopyle posted:

Async basically only helps with IO-bound tasks. If you are mostly CPU-bound you should probably use multiprocessing.

(I'm on phone and basically didn't even look at your code)

I agree with thermopyle. If you're actually pegging one of your CPUs asyncio is probably not the solution.

Eela6
May 25, 2007
Shredded Hen

Loving Africa Chaps posted:

Hello thread looking for some advice:

I'm currently doing a project that involves running some test models against a medium sized data set and i'm trying to see how i can optimise the code. I've used pool.map with 5 processes on my PC which gets me from 26.2 seconds to 10. When i profile the code it seems to be that the majority of the time is running this one function that gets called about 2million times when i run the model i've made across the data set:

code:
def wait_time(self, time_seconds):
        current_x1 = self.x1
        current_x2 = self.x2
        current_x3 = self.x3
        current_xeo = self.xeo

        self.x1 = current_x1 + (self.k21 * current_x2 - self.k12 * current_x1 + self.k31 * current_x3 - self.k13 * current_x1 - self.k10 * current_x1) * time_seconds
        self.x2 = current_x2 + (-self.k21 * current_x2 + self.k12 * current_x1) * time_seconds
        self.x3 = current_x3 + (-self.k31 * current_x3 + self.k13 * current_x1) * time_seconds
        self.xeo = current_xeo + (-self.keo * current_xeo + self.keo * current_x1) * time_seconds
Reducing the number of times this runs is not really an option but i wonder if this is maybe another option such as using a library so this function runs in pure C or something? does anyone think they might be useful?

You should do this with linear algebra and numpy. There's no need to use PyPy or anything like that - this is the exact use case for numpy's numeric computing tools. Don't wrap it in a class. If you give me the actual math or more context about you're trying to do, I can show you how.

Eela6
May 25, 2007
Shredded Hen

Loving Africa Chaps posted:

It's a series of differential equations

Would you mind giving me the differential equations? My skills are a little rusty but this is something I used to be pretty good at. I have an easier time with the mathematical notation. (Funnily enough, I had my old Numerical Methods for Ordinary Differential Systems book on my lap as you posted this - I'm putting all my books in cardboard boxes before I move.)

Eela6
May 25, 2007
Shredded Hen
I agree. Differential equations are prone to all sorts of numerical analysis problems. Don't roll your own solutions - use a known stable algorithm.

Eela6
May 25, 2007
Shredded Hen
Really? I had no idea.

(I rolled my own back when I was in academia, but that was part of my numerical analysis course work. I figured there had to be good libraries out there.)

Eela6
May 25, 2007
Shredded Hen

Philip Rivers posted:

What's the best way to store dynamic values in Python do y'all think? I have objects with elements that are constantly changing and need to be updated and then checked against each timestep and I'm not really very good at optimization!

This is a very vague question. Can you be more specific?

Eela6
May 25, 2007
Shredded Hen
Depending on the size of your simulation, I would worry about it too much. Use whatever you find most readable. If you find that it's too inefficient for the calculations you're trying to do, start looking into the numpy / scipy packages.

Eela6
May 25, 2007
Shredded Hen

Philip Rivers posted:

Yeah, I'm currently having efficiency issues. The naive implementation is pulling the endpoint positions from a list of the line objects but it's not fast enough. I don't know if a numpy array would be useful because since the positions are always updating I would need to rebuild the array every timestep.

Rebuilding numpy arrays is very fast, especially if you properly vectorize.

Eela6
May 25, 2007
Shredded Hen

Philip Rivers posted:

Do you have any resources on this? I'm very out of my depth with a lot of this and I'm just fumbling in the dark.

This video by Jake Vanderplass is a good start. https://www.youtube.com/watch?v=EEUXKG97YRw

Eela6
May 25, 2007
Shredded Hen
NaN == n is False, even if n is NaN. It's in the IEEE specificiations for floating point numbers. This is occasionally inconvenient but it's the way it is - the spec is older than Python!

This is true both for numpy and Python's built-in float type, though you're unlikely to encounter NaN in that case, since most operations that produce it will raise an exception first.

Eela6 fucked around with this message at 16:14 on Jul 4, 2017

Eela6
May 25, 2007
Shredded Hen
Learning to program is an iterative process. You're constantly going to go back to code you wrote a month ago and shudder at the quality of the code you wrote then - it's a natural part of the process. It's good to want to improve your code, but don't stress out too much. Every single good programmer was once a terrible programmer.

There's no single answer as to how best to structure your code. What is best depends on context. However, generally speaking, deeply nested dictionaries are a 'code smell' - it might be time to refactor and start working in classes.

Eela6
May 25, 2007
Shredded Hen
You may find this talk by Brett slatkin educational.

https://m.youtube.com/watch?v=D_6ybDcU5gc

Eela6
May 25, 2007
Shredded Hen

QuarkJets posted:

It looks like your Fighter class defines ages for various Races. It might be better if a single Age value is defined under CClass (because all characters should have an age), and then Fighter and Race can modify it, maybe using if statements to check the race and class type and then adjusting age appropriately.

To be more specific, you probably want to factor this out into a function something like this:

Python code:

class Fighter(CClass):
     starting_ages = {Human: (15, 1, 4)
                  Dwarf: (40, 5, 20)
                  ...}
     @classmethod
     def starting_age(cls, race):
          base, low, high = cls.starting_ages[race]
          return base+random.randint(low, high)

     def __init__(self, name: str, race: Race):
         self.name = name
         self.race = race
         self.age = self.starting_age(race)

Eela6 fucked around with this message at 21:50 on Jul 5, 2017

Eela6
May 25, 2007
Shredded Hen

Philip Rivers posted:

So here's a quick question, I got a bunch of nodes connected in a graph and I wanna store info and the chirality of those connections. Is there a pretty/Pythonic way I could assemble/sort lists by chirality?

If you just want to sort the list once, that's easy as pie:

Python code:
nodes = sorted(nodes, key = lambda node: node.chirality)
If, on the other hand, you'd like to maintain a sort by chirality, I recommendf the sortedcontainers module.

Python code:
nodes = sortedcontainers.SortedListWithKey(nodes, key=lambda node: node.chirality)
nodes.add(node) #insert a new node while maintaining the sort

Eela6 fucked around with this message at 01:53 on Jul 7, 2017

Eela6
May 25, 2007
Shredded Hen
You want to implement the magic method __eq__.

__eq__ is implemented like this:

Python code:
def __eq__(self, other):
    # return true if you know how to compare the two and self should == other
    # return false if you know how to compare the two and self should != other
    # return NotImplemented otherwise (this is a fallback that allows for further extension).
Here's how the interpreter actually uses the operator ==.


Python code:
def equals_op(a, b):
    try:
        f_result = a.__eq__(b)
        if f_result is not NotImplemented:
            return f_result
    except LookupError: # a does not implement __eq__
        pass

    try:
        b_result = b.__eq__(a)
        if b_result is not NotImplemented:
            return b_result
    except LookupError: # b does not implement __eq__
        pass
    return a is b

here's an example.

Python code:

class Person:
    def __init__(self, name):
        self.name = name



class Hero:
    def __init__(self, name, secret_identity):
        self.name = name
        self.secret_identity = secret_identity

    def __eq__(self, other):
        if not issubclass(type(other), Person):
            return NotImplemented
        return self.secret_identity == other.name

clark_kent = Person('clark kent')
superman = Hero(name='Superman', secret_identity= 'clark kent')

assert clark_kent == superman
assert superman == superman
assert clark_kent == clark_kent


Eela6 fucked around with this message at 21:03 on Jul 21, 2017

Eela6
May 25, 2007
Shredded Hen

onionradish posted:

I'd considered __eq__, and actually used it during the "upgrade" from the namedtuple to the class. Then, once the class __init__ changed, that broke and I needed to rethink. (I've been looking at the code for too long, so likely not thinking clearly.)

Is something like this a reasonable implementation to enable the comparison of the attributes? It works, but does it "smell"?

I'm fine with it, but I like dynamic magic. I would make the following changes

Python code:
class MyCustomThing:
    def _public_attribs(self):
        return {k:v for k,v in vars(self).items() if not k.startswith('_')}

    def __eq__(self, other):
        """Test equality with same type or dict"""
        if isinstance(other, MyCustomThing): #cleaner handling of subclassing
            return self._public_attribs() == other._public_attribs()
        elif isinstance(other, dict):
            return self._public_attribs() == other
        else:
            return NotImplemented #fall through in case the other thing has a more permissive __eq__
You could also get real fancy with duck typing and specify a contract instead.
Python code:
    def __eq__(self, other):
        """Test equality with same type or dict"""
        if hasattr(other, "_public_attribs"): #fufills contract
            return self._public_attribs() == other._public_attribs()
        elif isinstance(other, dict):
            return self._public_attribs() == other
        else: 
            return NotImplemented
A part of me really likes this solution.

If you want to go crazy, you can do this:
Python code:


class MyCustomThing:
    def __init__(self, a, b):
        self.a, self.b = a, b

    @property 
    def _public_attribs(self):
        return {k:v for k,v in vars(self).items() if not k.startswith('_')}

    def __eq__(self, other):
        """Test equality with dicts or others specifying _public_attribs contract"""
        return self._public_attribs == other
IN:
Python code:

superman = MyCustomThing("foo", "bar")
batman = MyCustomThing("foo", "bar")
aquaman = {"a": "foo", "b": "bar"}
steve = {"a": "steve"}

heroes = {'superman': superman, 'batman':batman, 'aquaman':aquaman, 'steve': steve}
for keya, heroa in heroes.items():
    for keyb, herob in heroes.items():
        print(f'{keya}=={keyb}: {heroa==herob}')
OUT:
code:
superman==superman: True
superman==batman: True
superman==aquaman: True
superman==steve: False
batman==superman: True
batman==batman: True
batman==aquaman: True
batman==steve: False
aquaman==superman: True
aquaman==batman: True
aquaman==aquaman: True
aquaman==steve: False
steve==superman: False
steve==batman: False
steve==aquaman: False
steve==steve: True

Eela6 fucked around with this message at 22:57 on Jul 21, 2017

Eela6
May 25, 2007
Shredded Hen
As far as NotImplemented vs NotImplementedError goes, read the docs at https://docs.python.org/3/library/constants.html or Ch. 13 of Fluent Python: Operator Overloading, or see this post I just made where I explained how the interpereter uses NotImplemented

Eela6 fucked around with this message at 22:59 on Jul 21, 2017

Eela6
May 25, 2007
Shredded Hen

onionradish posted:

I'd never seen that before. I learned something new! Thanks again.

EDIT: a follow up... in your "go crazy" example, you omit the hasattr(other, "_public_attribs") test inside __eq__. Is it not necessary?

Check this out.

0. self.__eq__(other) -> self._public_attribs == other
1. self._public_attribs.__eq__(other) is NotImplemented.
2. Fallback to other.__eq__(self._public_attribs) -> other._public_attributes == self.public_attribs.
3. These are both dictionaries, so they compare 'normally'.

Python is cool.

Eela6 fucked around with this message at 23:40 on Jul 21, 2017

Eela6
May 25, 2007
Shredded Hen

onionradish posted:

:psyboom:

My melon is officially twisted. I'm leaving the hasattr comparison in for explicitness, but I'm digging how slick that is.

:agreed:

I agree with your decision, actually. Explicit is better than implicit. I just wanted to show off :getin:

Eela6
May 25, 2007
Shredded Hen

Boris Galerkin posted:

Is it ok to do this?

code:
class Foo:
    def __init__(self, parameters):
        self.parameters = parameters

    def __getattr__(self, key):
        try:
            return self.__dict__['_' + key]

        except KeyError:
            value = bar(self.parameters[key])
            setattr(self, '_' + key, value)
            return getattr(self, key)
parameters would be a dict, and bar() would do some calculations that only need to be done once and can be reused, but I might not always need said value. So my intention was to just evaluate and cache it iff I needed to.

I'm just not really sure if it's ok to use the __dict__ attribute like I am, and if I'm using __getattr__ properly.

This seems like a take on lazy properties; i.e, calculate once, then store. I personally like the lazyproperty decorator described in the Python Cookbook by Beazley and Jones:

Python code:
class lazyproperty:
    def __init__(self, func):
        self.func = func

    def __get__(self, instance, cls):
        if instance is None:
            return self
        else:
            value = self.func(instance)
            setattr(instance, self.func.__name__, value)
            return value
Python code:
import math

class Circle:
    def __init__(self, radius):
        self.radius = radius

    @lazyproperty
    def area(self):
        print('Computing area')
        return math.pi * self.radius ** 2

    @lazyproperty
    def perimeter(self):
        print('Computing perimeter')
        return 2 * math.pi * self.radius
Python code:
>>> c = Circle(4.0)
>>> c.radius
4.0
>>> c.area
Computing area
50.26548245743669
>>> c.area
50.26548245743669
>>> c.perimeter
Computing perimeter
25.132741228718345
>>> c.perimeter
25.132741228718345
>>>

Eela6
May 25, 2007
Shredded Hen

Thermopyle posted:

Say i have a routine that searches for and gets a thing. You can search for a thing via a regex, via an int, or via a tuple. Which of the following do you prefer?

one
Python code:
 
def find_thing(filter):
  # code that type checks 'filter' and does the right thing.
two
Python code:
 
def find_thing_regex(regex):
def find_thing_int(an_int):
def find_thing_tuple(a_tuple):
three
Python code:
def find_thing(regex=None, an_int=None, a_tuple=None):

I would combine the first two approaches. The first approach is easiest for the user, the second is easiest for the developer.
code:
def find_thing(filter):
    if is_regex(filter):
        return _find_thing_regex(filter)
    elif is_instance(filter, int):
        return _find_thing_int(filter)
    elif is_instance(filter, tuple)
        return _find_thing_tuple(filter)
    else:
        raise TypeError("f'filter {filter!r} should be a regex, int, or tuple, but is a {type(filter)'})


Ed: A predicate is a fine approach.

Eela6
May 25, 2007
Shredded Hen
I completely forgot about singledispatch. I don't think I've ever used it, but maybe I should have.

Eela6
May 25, 2007
Shredded Hen

Jose posted:

i've started playing around with python for work mostly so i can make charts that can be tweeted out quickly or whatever. All i really want to do is import csv's so i can start using matplotlib stuff with them but finding an easy guide of doing this is really annoying me. I've spent a while playing with anaconda and i can import the csv using a couple of methods but they've all added stuff to the output. I'm just after either a decent guide using unicodecsv which seems to have replaced the csv package or the short bit of code that will get me an array or whatever where the first row of the csv is saved as column headers so I can stick things onto an x and y axis.

I only started doing the data camp courses that were free on friday so far

The csv module in the python standard library will work just fine for you. Here's an example to get you started.

Suppose we have a CSV of wedding guests, that contain their name, their relationship to the bride and groom, and their food preferences.

Here's our CSV:
code:
name,relationship,food_preferences
aaron,friend,kosher
amy,family,
steven,friend,vegetarian
It's saved as guests.csv

We want to process the list to find out which guests need what food. We can do so as follows:

IN
Python code:
import csv

needs_kosher, needs_vegetarian = [], []
with open('guests.csv') as guests_file:
    for guest in csv.DictReader(guests_file):
        if 'vegetarian' in guest['food_preferences']:
            needs_vegetarian.append(guest['name'])
        elif 'kosher' in guest['food_preferences']:
            needs_kosher.append(guest['name'])
        #vegetarian food is always kosher


print(f'needs_kosher: {needs_kosher}')
print(f'needs_vegetarian: {needs_vegetarian}')
OUT:
code:
needs_kosher: ['aaron']
needs_vegetarian: ['steven']

Eela6
May 25, 2007
Shredded Hen

Nippashish posted:

Seriously, do this. Do not even consider the csv reader in the stdlib. Pandas is infinitely superior.

I don't feel that way. I don't particularly like pandas, and I prefer using the stdlib where possible. You have to consider the audience of your code, too. Jose is very new to python; the last thing he needs is a thousand different APIs to understand.

Cingulate posted:

Situations where I can see the hand-crafted option make sense:
- you're analysing data and tweeting on an embedded system running python 2.6 on 128MB RAM
- you want to Learn Python the Hard and Manly Way

I am no fan of masochism. I just don't like solutions that are 'well, first install this dependency' for simple problems. I think you should use the level of tool that's appropriate for your problem.

If I'm using CSVs, I'm probably going to be doing it by hand. If I have a big dataset that requires the big guns,

1. I'm going to use xarray , not pandas
2. Why the hell am I using CSVs?

Eela6 fucked around with this message at 20:24 on Aug 14, 2017

Eela6
May 25, 2007
Shredded Hen

Thermopyle posted:

Probably, most people who need to read csv's don't need pandas, but it certainly seems like this person could use it.

Fair enough.

Eela6
May 25, 2007
Shredded Hen
I've now been working strictly in golang for about three months.

Having stepped away from Python, here the three things I miss the most:


1. Set type as a primitive
2. Comprehension literals (especially generator comprehensions!)
3. Context managers ( with statement)

Python is a good language.

Eela6
May 25, 2007
Shredded Hen

Munkeymon posted:

Anaconda would do all of that

This sounds like the perfect use case for Anaconda.

Spyder isn't great, but it will work just fine for students. It's as good of an 'IDE' for beginners as any, in my opinion.

(Spyder has the advantage of being being configured by default so that you can slam F5 and see the results of your script in a live IPython session in the bottom right corner. This is very helpful for beginners, especially in a math/scientific computing context. As a developer IDE, it's not great, but I think its just right for this.)

Eela6
May 25, 2007
Shredded Hen

QuarkJets posted:

IIRC the people who made Spyder were actively trying to mimic the Matlab IDE, to act as an entry point to former Matlab users who aren't already fully consumed by Stockholm's Syndrome

Huh. That explains why I took to Spyder immediately as a new Python programmer (I learned to program in MATLAB)

numpy-in-spyder vs. MATLAB are remarkably similar, with the exception that numpy is good

Eela6 fucked around with this message at 00:22 on Sep 15, 2017

Adbot
ADBOT LOVES YOU

Eela6
May 25, 2007
Shredded Hen

Daviclond posted:

Why does this one-liner:

code:
return my_list.reverse()
return None, but over two lines this:
code:
my_list.reverse()
return my_list
returns the reversed list as intended?

I thought returning code which had to be evaluated (e.g. "return x == y") was fine, so I'm clearly missing something here. Is there a better way to do it?

Let's look at this in a little more detail.

list.reverse() is a method which reverses the list in place. It returns None.


IN:
Python code:
a = [1, 2, 3]
b = a.reverse()
print(a)
print(b)
OUT:
pre:
[3, 2, 1]
None
On the other hand, reversed() called on a list creates a new iterator, which iterates through each element of the list, starting from the back. This is cool, because you don't have to create a new list to iterate through it backwards. On the other hand, to get a list from it, you'll have to call list() to evaluate the generator.

Python code:
a = [1, 2, 3]
b = reversed(a)
print(b)
print(a)
print(list(b))
pre:
<list_reverseiterator at 0x2f46d9ef0f0>
[1, 2, 3] 
[3, 2, 1]
The best most terse way to simply create a reversed list or tuple is with a slice:
Python code:
a = [1, 2, 3]
b = a[::-1]
print(b)
print(a)
pre:
[3, 2, 1]
[1, 2, 3]

Eela6 fucked around with this message at 01:08 on Sep 16, 2017

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply