I have a problem that asks me to combine three numeric variables, for example, a = 1 , b = 2 , c = 3. We're supposed to make d = ' 1|2|3 '. I've done some scripting in BASH where "|" refers to piping. How would you accomplish this in Python, and what does "|" mean?
The vertical bar is merely a character. Treat this the same way you would a comma or a dash. Convert each integer to string, and concatenate them with the bar in between. This is merely an exercise in string manipulation; nothing particularly deep or tricky.
Not sure what exactly you are expected to do or mean by "combining". In Python you can combine variables into tuples so that you can have a "compound" or combined variable that you can use for lookup tables, etc.
a = 1
b = 2
c = 3
combined = (a,b,c)
now you can do things like x = {combined: "value"}
The solution hspandher is on the right track, but would work primarily for one set of three numeric variables. It might be more useful to create a function like this:
def numberCombiner(a, b, c):
return str(a)+"|"+str(b)+"|"+str(c)
numberCombiner(1,2,3)
Which would take in three numeric values and output the string you want. Then you can call/invoke the numberCombiner function on different values, like:
numberCombiner(2,3,4)
which would return
>>> '2|3|4'
Using format:
>>> a=1
>>> b=2
>>> c=3
>>> "{}|{}|{}".format(a,b,c)
'1|2|3'
Just create a list of all the variables, and join them using the pipe symbol.
"|".join(map(str, [a, b, c]))
Use a generator expression to convert your integer variables into strings, and join them with the vertical line symbol.
"|".join(str(v) for v in [a, b, c])
More about generator expression.
More about string joining.
Thanks to juanpa.arrivillaga for pointing out the generator expression syntax where the generator is used right away by an enclosing function. See comments for more information.
Related
I have a list and a function f which returns a 3-tuple. I would like to capture the first two return values, and with the third, append to lst. I know I can do the following:
a, b, c = f()
lst.append(c)
but I would like a way not to have the extraneous variable "c". I know I can also do:
lst.append(f()[2])
but I do not want to throw away the other two return values.
Any suggestions?
Edit: I appreciate the answers provided, but the question, put more clearly, is to find a neat one-liner.
Assign the return value to a local variable before you append the result.
No, you can't catch two values and append the third in one statement; you only get one "verb" per command.
result = f()
lst.append(result[2])
What you want to do is not possible with a "one liner" (without using semi-colon to fit two statements on a single line) unless you change your function definition.
Specifically, define f() in the following way:
def f(list_to_append_to):
a = ...
b = ...
c = ...
list_to_append_to.append(c)
return a, b
Then:
a, b = f(mylist)
If your problem is not saving yourself with writing one more line of code, but you would just want the function call, the assignment and the appendix in a single statement, you could use a wrapper function:
def append_and_assign(mylist, myfunc):
a, b, c = myfunc()
mylist.append(c)
return a,b,c
and so you can call:
a,b,c = append_and_assign(lst, f)
Given this harmless little list:
>>> lst = ['o','s','s','a','m','a']
My goal is to Pythonically concatenate the little devils using one of the following ways:
A. A plain old string function to get the job done, short, no imports
>>> ''.join(lst)
'ossama'
B. Lambda, lambda, lambda
>>> reduce(lambda x, y: x + y, lst)
'ossama'
C. Globalization (do nothing, import everything)
>>> import functools, operator
>>> functools.reduce(operator.add, lst)
'ossama'
What are other Pythonic ways to achieve this magnanimous task?
Please rank (Pythonic level) and rate solutions giving concise explanations.
In this case, is the most pythonic solution the best coding solution?
''.join(lst)
The only Pythonic way:
clear (that is what all the big boys do and what they expect to see),
simple (no additional imports needed, and stable across all versions),
fast (written in C) and
concise (on an empty string, join elements of iterable!).
Have a look at Guido's essay on Python optimization. It covers converting lists of numbers to strings. Unless you have a good reason to do otherwise, use the join example.
Of course it's join. How do I know? Let's do it in a really stupid way:
If the problem was only adding 2 strings, you'd most likely use str1 + str2. What does it take to get that to the next level? Instinctively, for most (I think), will be to use sum. Let's see how that goes:
In [1]: example = ['a', 'b', 'c']
In [2]: sum(example, '')
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython console> in <module>()
TypeError: sum() can't sum strings [use ''.join(seq) instead]
Wow! Python simply told me what to use! :)
Here's the least Pythonic way:
out = ""
for x in range(len(lst)):
for y in range(len(lst)):
if x + y == len(lst)-1:
out = lst[y] + out
I myself use the "join" way, but from Python 2.6 there is a base type that is little used: bytearray.
Bytearrays can be incredible useful -- for string containing texts, since the best thing is to have then in Unicode, the "join" way is the way to go -- but if you are dealing with binary data instead, bytearrays can be both more Pythonic and more efficient:
>>> lst = ['o','s','s','a','m','a']
>>> a = bytearray(lst)
>>> a
bytearray(b'ossama')
>>> print a
ossama
It is a built-in data type: no imports needed - just use then -- and you can use a bytearray instead of a list to start with - so they should be more efficient than the "join", since there isn’t any data copying to get the string representation for a bytearray.
There is a great answer from SilentGhost, but just a few words about the presented reduce "alternative":
Unless you've got a very very very good reason to concatenate strings using + or operator.add (the most frequent one, that you've got few, fixed number of strings), you should use always join.
Just because each + generates a new string which is the concatenation of two strings, unlike join that only generates one final string. So, imagine you've got three strings:
A + B + C
-->
D = A + B
final = D + C
Ok, it doesn't seems not much, but you've got to reserve memory for D. Also, due Python's use of strings, generating a new, intermediate, string, it's somehow expensive...
Now, with five strings,
A + B + C + D + E
-->
F = A + B
G = F + C
H = G + D
final = H + E
Assuming the best scenario (if we do (A+B) + (C+D) + E, we'll end having three intermediate strings at the same time on memory), and that's generating three intermediate strings... You've got to generate a new Python object, reserve memory space, and release the memory a few times... Also there is the overhead of calling a Python function (that is not small).
Now think of it with 200 strings. We'll end up with a ridiculous big number of intermediate strings, each of which is consuming combining quite a lot of time on being a complete list over Python , and calling a lot of operator.add functions, each with its overhead...
Even if you use reduce functions, it won't help. It's a problem that has to be managed with a different approach: join, which only generates one complete Python string, the final one and calls one Python function.
(Of course, join, or other similar, specialized function for arrays.)
I am coping with the formatting of numbers. I assumed that the .format allows to use multiple arguments:
a = 1.11111111111
b = 0.9
s = '({0:.2f}, {0:.2f})'.format(a, b)
print(s)
Returns:
'(1.11, 1.11)'
Instead of:
'(1.11, 0.90)'
On the other hand, this works fine:
'({}, {})'.format(a, b)
Returns:
'(1.11111111111111, 0.9)'
Any idea where is the problem?
You used for both of the the parameters the value a (0), you should call in the second param to value b (1).
the value before the : is for giving placeholders an explicit positional index.
This allows for re-arranging the order of display without changing the arguments.
Change
s = '({0:.2f}, {0:.2f})'.format(a, b)
To:
s = '({0:.2f}, {1:.2f})'.format(a, b)
Values before the : character specify either a field name or a conversion; by using 0 in both cases you're essentially telling .format, via the element index, to use a in both cases.
In your second case, '({}, {})'.format(a, b), by not specifying a position, .format replaces each empty pair of {} with the elements supplied in increasing order of position.
A simple replacement, as suggested, is to use 1 to indicate that you want to use b instead of a. Alternatively, simply omit them:
s = '({:.2f}, {:.2f})'.format(a, b)
to get a similar effect.
You should skim through the Syntax for the format strings to get an idea of the rules used when formatting.
This is newbie question. I am working on something called sagemath which is completely based on Python.
My code is two parts:
The first part is:
var('a,b')
my_list=list(powerset([a,b]))
my_possible_products_list=[]
for i in my_list:
if len(i)!=0:
my_possible_products_list.append(prod(i))
print my_possible_products_list
with an ouput
[a, b, a*b]
i.e, the result is a list of all possible product expressions on a set of two variables.
The second part:
for expression_compute in my_possible_products_list:
for l in range(1,3):
for a in divisors(l):
for b in divisors(l):
print expression_compute
with an output
a
a
a
a
a
b
b
b
b
b
a*b
a*b
a*b
a*b
a*b
The problem: I need to have numerical output, not using a and b, but using the values of a and b as divisors of the given l.
Any hint?
Thanks.
Not sure if I understand the question here, but to my understanding you have the expression as a string and want to compute the value. For a and b as single entities it's easy, just cast to integer
a = "5"
print(int(a) + 1) # Will print 6
for the product expression you could do as #iForest suggests using eval() but as he said that is evil. I would use the split method
expr = "3*5"
terms = expr.split('*')
print(int(terms[0]) * int(terms[1])) # Will print 15
hope this helps, otherwise I need more explanation of your problem
== Updates after #iForest comment ==
If it is the variables names as strings that are needed use locals()
a = 3
b = 5
variables = locals()
expr = "a*b"
terms = expr.split('*')
print(variables[terms[0]] * variables[terms[1]]) # Output 15
will work as long as you don't need to update the variables
Built-in function eval() can evaluate value of string.
a = 3
b = 5
print(eval("a * b")) # Output 15
But yes, eval() is EVIL.
It's easy and quick to use, but be careful when you use it. You have to make sure the input string you eval() is OK. Read more about how to use / how dangerous here (8.9. Evaluating Arbitrary Strings As Python Expressions).
I was reading the assignment statements in the Python docs ( http://docs.python.org/reference/simple_stmts.html#assignment-statements).
In that it is quoted that:
If the target is a target list enclosed in parentheses or in square brackets: The object must be an iterable with the same number of items as there are targets in the target list, and its items are assigned, from left to right, to the corresponding targets.
After reading it, I thought of writing a sample like this:
a = 5
b = 4
a, b = a + b, a
print a, b
My assumption was that a and b both should have the value of 9.
However, I am proven wrong. 'a' has the value of 9 and 'b' has the value of 5.
Can some one help me understand this better? Why the older value of 'a' is assigned rather than the new one? As per the docs, a's value will be assigned first right? Am I missing something?
All the expressions to the right of the assignment operator are evaluated before any of the assignments are made.
From the Python tutorial: First steps towards programming:
The first line contains a multiple assignment: the variables a and b simultaneously get the new values 0 and 1. On the last line this is used again, demonstrating that the expressions on the right-hand side are all evaluated first before any of the assignments take place. The right-hand side expressions are evaluated from the left to the right.
Emphasis mine.
Your code is functionally equivalent to the following:
a, b = 5 + 4, 5
print a, b
Python does not have a "comma operator" as in C. Instead, the comma indicates that a tuple should be constructed. The right-hand side of
a, b = a + b, a
is a tuple with th two items a + b and a.
On the left-hand side of an assignment, the comma indicates that sequence unpacking should be performed according to the rules you quoted: a will be assigned the first element of the tuple, b the second.
You can think of the assignments happening in parallel on copies rather than sequentially and in-place.
This is why in python you dont need a swap function:
a, b = b, a
works sufficiently without requiring a temp variable, c.