How would I print a list of strings as their individual variable values?
For example, take this code:
a=1
b=2
c=3
text="abc"
splittext = text.split(text)
print(splittext)
How would I get this to output 123?
You could do this using eval, but it is very dangerous:
>>> ''.join(map(lambda x : str(eval(x)),Text))
'123'
eval (perhaps they better rename it to evil, no hard feelings, simply use it as a warning) evaluates a string as if you would have coded it there yourself. So eval('a') will fetch the value of a. The problem is that a hacker could perhaps find some trick to inject arbitrary code using this, and thus hack your server, program, etc. Furthermore by accident it can perhaps change the state of your program. So a piece of advice is "Do not use it, unless you have absolutely no other choice" (which is not the case here).
Or a less dangerous variant:
>>> ''.join(map(lambda x : str(globals()[x]),Text))
'123'
in case these are global variables (you can use locals() for local variables).
This is ugly and dangerous, because you do not know in advance what a, b and c are, neither do you have much control on what part of the program can set these variables. So it can perhaps allow code injection. As is advertised in the comments on your question, you better use a dictionary for that.
Dictionary approach
A better way to do this is using a dictionary (as #Ignacio Vazquez-Abrams was saying):
>>> dic = {'a':1,'b': 2,'c':3}
>>> ''.join(map(lambda x : str(dic[x]),Text))
'123'
List instead of string
In the above we converted the content to a string using str in the lambda-expression and used ''.join to concatenate these strings. If you are however interested in an array of "results", you can drop these constructs. For instance:
>>> map(lambda x : dic[x],Text)
[1, 2, 3]
The same works for all the above examples.
EDIT
For some reason, I later catched the fact that you want to print the valuesm, this can easily be achieved using list comprehension:
for x in Text :
print dic[x]
again you can use the same technique for the above cases.
In case you want to print out the value of the variables named in the string you can use locals (or globals, depending on what/where you want them)
>>> a=1
>>> b=2
>>> c=3
>>> s='abc'
>>> for v in s:
... print(locals()[v])
...
1
2
3
or, if you use separators in the string
>>> s='a,b,c'
>>> for v in s.split(','):
... print(locals()[v])
...
1
2
3
Related
Someone posted this interesting formulation, and I tried it out in a Python 3 console:
>>> (a, b) = a[b] = {}, 5
>>> a
{5: ({...}, 5)}
While there is a lot to unpack here, what I don't understand (and the semantics of interesting character formulations seems particularly hard to search for) is what the {...} means in this context? Changing the above a bit:
>>> (a, b) = a[b] = {'x':1}, 5
>>> a
{5: ({...}, 5), 'x': 1}
It is this second output that really baffles me: I would have expected the {...} to have been altered, but my nearest guess is that the , 5 implies a tuple where the first element is somehow undefined? And that is what the {...} means? If so, this is a new category of type for me in Python, and I'd like to have a name for it so I can learn more.
It's an indication that the dict recurses, i.e. contains itself. A much simpler example:
>>> a = []
>>> a.append(a)
>>> a
[[...]]
This is a list whose only element is itself. Obviously the repr can't be printed literally, or it would be infinitely long; instead, the builtin types notice when this has happened and use ... to indicate self-containment.
So it's not a special type of value, just the normal English use of "..." to mean "something was omitted here", plus braces to indicate the omitted part is a dict. You may also see it with brackets for a list, as shown above, or occasionally with parentheses for a tuple:
>>> b = [],
>>> b[0].append(b)
>>> b
([(...)],)
Python 3 provides some tools so you can do this with your own objects, in the form of reprlib.
Some (many? all?) functional programming languages like StandardML and Haskell have a type of expression in the form let ... in ... where is possible to create temporary variables with the scope of the expression itself.
Example: let a=b*c in a*(a+1)
It seems that in Python there is no expression construct similar to this.
Motivation:
For example the body of a lambda function must be a (one) expression. Not two expressions. Not a statement (an assignment is a statement and not an expression).
Moreover, when writing functional expressions and in general one-liners in python, things can become messy pretty easily (see my answer to Python 2 list comprehension and eval).
The point of such a construct is to avoid repetition (which sometimes leads to re-computation), for example l[:l.index(a)]+l[l.index(a)+1:] instead of an hypothetic let i=l.index(a) in l[:i]+l[i+1:]
How can we achieve a similar language feature in python2 / python3?
This isn't really idiomatic code, but for single expressions you can use lambdas that you immediately invoke. Your example would look like this:
>>> b, c = 2, 3
>>> (lambda a: a * (a + 1))(b * c)
42
You can also write this using keyword arguments if that helps readability:
>>> (lambda a: a * (a + 1))(a=b * c)
42
You can sort of simulate a smaller scope for your temporary variable by putting it into an iterable and then looping over that iterable:
>>> b,c = 2,3
>>> var = [a*(a+1) for a in [b*c]][0]
>>> var
42
This puts the single value b*c into a list, then loops over that list in a comprehension, with each new value consisting of some transformation of each element. The created list is one element in length, and we get the first element in it with [0]. Without the comprehension, it looks as follows:
>>> b,c = 2,3
>>> var = []
>>> for a in [b*c]:
... var.append(a*(a+1))
...
>>> var = var[0]
>>> var
42
I have three indexes, x,y,t and a tridimensional matrix (it's actually a netcdf variable) in python but the order in which the indexes have to be applied to the matrix change. So, to make it easily user-definable I am trying to get the specific element I want as
order='t,x,y' # or 't,y,x' or anything like this
elem=matrix[eval(order)]
but this fails with TypeError: illegal subscript type. When I try
a=eval(order)
print type(a)
it gives me that a is a tuple, so I'm guessing this is the source of my problem. But why is a a tuple? Any ideas as how to do this? Documentation wasn't helpful.
Also, somehow doing
a=eval(order)
i,j,k=a
elem=matrix[i,j,k]
doesn't work either. Not sure as to why.
EDIT
People are misunderstanding what I'm trying to do here apparently, so let me explain a little better. This is inside a function where the values x, y, t are already defined. However, the order in which to apply those indexes should be provided by the user. So the call would be something like func(order='t,x,y'). That's at least the only way I figured the user could pass the order of the indexes as a parameter. Sorry for the confusion.
Why is a a tuple?
Because it is: if you leave eval() out of the picture, you get the same, when you are just using commas:
>>> a = 1, 2, 3
>>> type(a)
<type 'tuple'>
do instead this:
Give the order directly as list, lists maintain order:
def some_method(order=None):
order = order or [t, y, x]
# t, y, x have to be known out side this scope
...
If your t, x, y are only known within the scope, you - of course - have to
give the order in a symbolic way, thus back to eval. Here you assume knowledge about the inner state of your function
def some_method(order='t,x,y'):
order = eval(order)
...
elem = matrix[order[0]][order[1]][order[2]]
EDIT
wims answer shows how to avoid eval() which should be preferred at least when the input to this function would come from an untrusted source, because eval() would gladly run arbitrary python code.
You should try to avoid using eval for this. It's hacky and ugly, and it's easily possible to avoid it just by making a lookup dict.
>>> order = 'x,y,t' # this is specified outside your function
You can still pass this string into your function if you want:
>>> # this is inside your function:
>>> t,x,y = 0,1,2 # I don't know what your actual values are..
>>> lookup = {'t': t, 'x': x, 'y': y} # make this inside your function
>>> tuple_ = tuple(lookup[k] for k in order.split(','))
>>> tuple_
(1, 2, 0)
Now use the tuple_ to index your array.
I think what you're looking for is called "slicing", or even "extended slicing", depending on the data format you're slicing. Oh, and you don't need eval for that at all, tuples would do just fine.
See also this question:
Explain Python's slice notation
I very like quite new Python convention to print things with .format()
Is it possible using it to print element line by line. Assuming of course number of elements is unknown.
Working example will be appreciated.
If you are using Python 3.x and your intention is to just printing the list of elements, one in each line, then you can use print function itself, like this
my_list = [1, 2, 3, 4]
print(*my_list, sep="\n")
*my_list simply unpacks the list elements and pass each one of them as parameters to the print function (Yes, print is a function in Python 3.x).
Output
1
2
3
4
If you are using Python 2.x, then you can just import the print function from the future like this
from __future__ import print_function
Note: This import should be the first line in the file.
You can use the string formatter on really any kind of string, including multi-line string. So of course, if you had a format string '{}\n{}\n{}' you could pass three items to it, and they would be all placed on separate lines.
So with a dynamic number of elements you want to print, all you need to do is make sure that the format string contains the same number of format items too. One way to solve this would be to construct the format string dynamically. For example this:
'\n'.join('{}' for _ in range(len(my_list))).format(*my_list)
So you essentially create a format string first, by having a generator produce one format item {} per element in my_list, and joining these using a newline character. So the resulting string looks something like this: {}\n{}\n…\n{}\n{}.
And then you use that string as the format string, and call format on it, passing the unpacked list as arguments to it. So you are correctly filling all spots of the format string.
So, you can do it. However, this is not really a practical idea. It looks rather confusing and does not convey your intention well. A better way would be to handle each item of your list separately and format it separately, and only then join them together:
'\n'.join('{}'.format(item) for item in my_list)
As for just printing elements line by line, of course, the more obvious way, that wouldn’t require you to build one long string with line breaks, would be to loop over the items and just print them one-by-one:
for item in my_list:
print(item)
# or use string formatting for the item here
print('{}'.format(item))
And of course, as thefourtheye suggested, if each loop iteration is very simple, you can also pass the whole list to the print function, and set sep='\n' to print the elements on separate lines each.
You mean like print('\n'.join(a_list))? String formatting could probably do something similar to '\n'.join(a_list), but it doesn't seem necessary here. (see update)
The thing is, .format doesn't print things at all. That's what print is for. format takes some data and returns a string. print is one way to output that string to the terminal/standard output, but print and .format don't really have any real relationship.
Update:
I take back what I said about string formatting being able to do this. The format pattern itself predefines the arity of the format method, so short of dynamically building the format pattern, you can't use format for this.
Keep It Simple
>>> myList = [2,3,5,6,5,4,3,2]
>>> for elem in myList:
'{}'.format(elem)
gives
'2'
'3'
'5'
'6'
'5'
'4'
'3'
'2'
Is it what you wish obtain?
We can use join to print line by line:
>>> x = ['a','b','c']
>>> print("\n".join(x))
a
b
c
Another way to do it is to use string multiplication:
my_list = [1, 2, 3, 4, 5]
print(('{}\n'*len(my_list)).format(*my_list))
For plain old printing, I'd use the sep option of the print command. The format method is more useful if you are using the python logging facilities (which do not have the sep argument).
Using module pprint - Data pretty printer
>>> import pprint
>>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
>>> stuff.insert(0, stuff[:])
>>> pp = pprint.PrettyPrinter(indent=4)
>>> pp.pprint(stuff)
[ ['spam', 'eggs', 'lumberjack', 'knights', 'ni'],
'spam',
'eggs',
'lumberjack',
'knights',
'ni']
one more idea to get the string not needing to print it:
my_list = [1, 2, 3, 4]
str("{}\n"*len(my_list)).format(*my_list)
i want to create a string S , which can be used as an array , as in each element can be used separately by accesing them as an array.
That's how Python strings already work:
>>> a = "abcd"
>>> a[0]
'a'
>>> a[2]
'c'
But keep in mind that this is read only access.
You can convert a string to a list of characters by using list, and to go the other way use join:
>>> s = 'Hello, world!'
>>> l = list(s)
>>> l[7] = 'f'
>>> ''.join(l)
'Hello, forld!'
I am a bit surprised that no one seems to have written a popular "MutableString" wrapper class for Python. I would think that you'd want to have it store the string as a list, returning it via ''.join() and implement a suite of methods including those for strings (startswith, endswith, isalpha and all its ilk and so one) and those for lists.
For simple operations just operating on the list and using ''.join() as necessary is fine. However, for something something like: 'foobar'.replace('oba', 'amca') when you're working with a list representation gets to be ugly. (that=list(''.join(that).replace(something, it)) ... or something like that). The constant marshaling between list and string representations is visually distracting.