Best way to assign a list in var

Writing something in Python. Have a piece of code, would like to know if it can be done more elegantly ...

# Statistics format is - done|remaining|200's|404's|size statf = open(STATS_FILE, 'r').read() starf = statf.strip().split('|') done = int(starf[0]) rema = int(starf[1]) succ = int(starf[2]) fails = int(starf[3]) size = int(starf[4]) ... 

It continues. I wanted to know if, after splitting a string into a list, is there a better way to assign each list to var. I have about 30 rows that assign vars index values. Just trying to learn more about Python, what it ...

+4
source share
5 answers
 done, rema, succ, fails, size, ... = [int(x) for x in starf] 

it is better:

 labels = ("done", "rema", "succ", "fails", "size") data = dict(zip(labels, [int(x) for x in starf])) print data['done'] 
+6
source

What I don't like about the answers right now is that they all stick together in one expression. You want to reduce redundancy in your code without doing too much at once.

If all the elements in the string are ints, then convert them all together, so you do not need to write int(...) every time:

 starf = [int(i) for i in starf] 

If only some elements are ints - perhaps some of them are strings or float - then you can convert only those:

 for i in 0,1,2,3,4: starf[i] = int(starf[i])) 

Assigning in blocks is helpful; if you have a lot of items - you said that you have 30 - you can separate it:

 done, rema, succ = starf[0:2] fails, size = starf[3:4] 
+5
source

I could use separator csv module | (although this may be redundant if you are "sure" that the format will always be super-simple, single-line, no lines, etc., etc.). Like your low-level line processing, the csv reader will give you the lines, and you will need to call int for each (with a list or map call) to get integers. Other tips include using the with statement to open the file to ensure that it does not cause a “file descriptor leak” (not necessarily in the current version of CPython, but a great idea for portability and checking the future).

But I doubt the need to create 30 separate descriptors to represent 30 related values. Why not create, for example, the type collections.NamedTuple with the corresponding names and initialize its instance, and then use qualified names for the fields, i.e. Beautiful namespace? Remember the last koan in Zen of Python ( import this at the prompt of the interpreter): “Namespaces are one of the best ideas that allow you to do this!” ... benenames has its own (limited ;-) place, but representing dozens of related meanings one thing - rather, this situation "screams" for the "let me do more" approach (that is, adding one suitable namespace combining related fields is a much better way to organize your data).

+4
source

Using a Python dict is probably the most elegant choice.

If you put your keys on a list as such:

 keys = ("done", "rema", "succ" ... ) somedict = dict(zip(keys, [int(v) for v in values])) 

This will work. :-) Looks better than 30 lines :-)

EDITOR: I think there are dictations now, so it might look even better! :-)
EDIT Part 2: Also, for a collection of keys you want to split this into multi-line strings.
EDIT Again: bug fixed :)

0
source

Thanks for all the answers. So here's the summary -

  • Glenn's answer was to deal with this problem in blocks. those. done, rema, succ = starf[0:2] , etc.
  • Leoluk's approach was shorter and more enjoyable, taking advantage of python's extremely powerful dict concepts.
  • Alex's answer was more design oriented. Loved this approach. I know that this should be done as Alex suggested, but this requires a lot of re-factoring of the code. Not the right time for this now.
  • townsean - same as 2

I reviewed Leoluk's approach. I'm not sure what speed it is? I do not know if List / Dict was accepted at runtime. But at the moment, it significantly reduces the size of my code. I will optimize when such a need arises :) Go - "Pre-mature optimization is the root of all evil" ...

0
source

All Articles