Concatenating string and integer in Python - python

In Python say you have
s = "string"
i = 0
print s + i
will give you error, so you write
print s + str(i)
to not get error.
I think this is quite a clumsy way to handle int and string concatenation.
Even Java does not need explicit casting to String to do this sort of concatenation.
Is there a better way to do this sort of concatenation, i.e, without explicit casting in Python?

Modern string formatting:
"{} and {}".format("string", 1)

No string formatting:
>> print 'Foo',0
Foo 0

String formatting, using the new-style .format() method (with the defaults .format() provides):
'{}{}'.format(s, i)
Or the older, but "still sticking around", %-formatting:
'%s%d' %(s, i)
In both examples above there's no space between the two items concatenated. If space is needed, it can simply be added in the format strings.
These provide a lot of control and flexibility about how to concatenate items, the space between them etc. For details about format specifications see this.

Python is an interesting language in that while there is usually one (or two) "obvious" ways to accomplish any given task, flexibility still exists.
s = "string"
i = 0
print (s + repr(i))
The above code snippet is written in Python 3 syntax, but the parentheses after print were always allowed (optional) until version 3 made them mandatory.

In Python 3.6 and newer, you can format it just like this:
new_string = f'{s} {i}'
print(new_string)
Or just:
print(f'{s} {i}')

The format() method can be used to concatenate a string and an integer:
print(s + "{}".format(i))

You can use the an f-string too!
s = "string"
i = 95
print(f"{s}{i}")

Let's assume you want to concatenate a string and an integer in a situation like this:
for i in range(1, 11):
string = "string" + i
And you are getting a type or concatenation error.
The best way to go about it is to do something like this:
for i in range(1, 11):
print("string", i)
This will give you concatenated results, like string 1, string 2, string 3, etc.

If you only want to print, you can do this:
print(s, i)

Related

most efficient (and pythonic) way to concatenate strings in python without leaving immutable chunks behind [duplicate]

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.)

Create tuple list of key,val from another list of values in Python

I have the following python list in
[0,1,2,'def','ghi']
Now I want to convert above into another list of tuples by discarding first list item so for e.g. I want [(1,0),(2,1),('def',2),('ghi',3)]
I have the following code
point = [0,1,2,'def','ghi']
spliltm0 = split[1:]
ls = ()
int i = 0
for a in spliltm0:
ls = (a,i++)
The above seems to be long code for Python, is there any shorter version of above code? I am super new to Python.
That code isn't Python at all, since you do int i and i++, neither of which are Python*; also, strip() and split() are methods on strings, not lists.
Your result can be achieved in a one-line list comprehension:
result = [(elem, i) for i, elem in enumerate(point[1:])]
* i++ is syntactically valid in Python, but doesn't at all do what you think it does.
You need to be clear about the basics of Python before asking in the Python Forum.
1) You cannot apply strip function on a 'list' object, It should be string object.
2) spliltm0 = split[1:], Here split is treated as string, and is not defined. Also split is a string method which should not be used as a variable for storing string.
3) int i = 0 This is a format of C/C++. Not applicable to Python
4)
for a in spliltm0:
ls = (a,i++)
i++ is not available in Python. Refer to this link (Why are there no ++ and --​ operators in Python?)

replace '0xNN' with a byte in a string in python

I have string say
string1 = '0x000x200x300x00'
I want result like
result = '\x00\x20...'
I want to replace every '0x' with '\x' . How to do it ?
I have tried replace function in python like as follows
y = x.replace('0x', '\x')
y = x.replace('0x', '\\x')
y = x.replace('0x', r'\x')
But no success :( .
Can anyone help in this issue ?
string1.replace("0x","\\x") use `\\` to escape the `\`
/ is also not the same as\.
string1 = '0x000x200x300x00'
print string1.replace("0x","\\x")
\x00\x20\x30\x00
In [19]: string1 = '0x000x200x300x00'
In [20]: print string1.replace("0x","\\x") # str
\x00\x20\x30\x00
In [21]: string1.replace("0x","\\x") # repr
Out[21]: '\\x00\\x20\\x30\\x00'
What exactly are your trying to accomplish?
I am a bit wary to post this answer because it does not directly answer your question, but I assume you want to do some byte-mangling (wild guess) as you were not very explicit in your question.
If that's the case, then here's another "thing" you might want to do:
data = [int(_, 16) for _ in string1.split('0x')[1:]]
This will give you a list of ints representing the "byte"(?) values (of course depends what you want to do...)
The above code makes a couple of assumptions based on your example input:
The input string will start with 0x
The input string does not include any non-escaped values. In other words, you always have a sequence of 0xnn strings with nothing else in between!

python: how do i know when i am on the last for cycle

for i in range(len(results_histogram)):
if i!=len(results_histogram)-1:
url+=str(results_histogram[i])+','
my if statement is checking whether i am on the last loop, but it is not working. what am i doing wrong?
To avoid the question slightly, you seem to have rewritten str.join:
','.join(results_histogram)
If you get an error like TypeError: sequence item 0: expected string, int found, then you can convert the intermediate results to a string with
','.join(map(str, results_histogram))
str.join is undoubtedly more efficient than concatenating multiple strings in a loop, because in Python, strings are immutable, so every concatenation results in the creation of a new string, which then has to be garbage collected later.
Specifically, your example is "not working" because you skip the last element entirely, when you only want to skip adding the comma. This is clear and obvious with a small example:
>>> x = [1,2,3]
>>> for i in range(len(x)):
... if i != len(x) - 1:
... print str(x[i]) + ',',
...
1, 2,
So you could rewrite your example as
for i in range(len(results_histogram)):
url += str(results_histogram[i])
if i!=len(results_histogram)-1:
url += ','
But you should still stick with str.join.
I agree with #Mark Rushakoff in that using join would be the best. I wanted to just comment on this but I do not have enough rep to do so =(
Anyways, also look into the built-in enumerate() function. The documentation can be found here.
A way you could've coded your solution using enumerate would be:
for i, res in enumerate(results_histogram):
url+=res
if i != len(results_histogram)-1:
url+=','
Assuming url is declared somewhere previously. Again, using join for your situation would be better. This is just showing you enumerate for future situations where you might want to do something besides string concatenation.
Mark is certainly right for your example, but sometimes cases like this occur where there doesn't exist such an elegant alternative. Then you could do something like:
if len(results_histogram):
url += str(results_histogram[0])
for i in range(len(results_histogram))[1:]:
url += ',' + str(results_histogram[i])
Using a variable to increment through a list is generally unnecessary. A slice will return everything except the last element.
This example follows your syntax:
for el in results_histogram[:-1]:
url += str(el) + ','
Or you can complete the whole thing with a generator expression:
','.join(str(el) for el in results_histogram[:-1])
ouput = "("
for telem in text[:-1]:
output += "%s, " % telem
output += "%s)\n" % text[-1:]

String representation of arrays in python

Is there anything that performs the following, in python? Or will I have to implement it myself?
array = [0, 1, 2]
myString = SOME_FUNCTION_THAT_TAKES_AN_ARRAY_AS_INPUT(array)
print myString
which prints
(0, 1, 2)
Thanks
You're in luck, Python has a function for this purpose exactly. It's called join.
print "(" + ", ".join(array) + ")"
If you're familiar with PHP, join is similar to implode. The ", " above is the element separator, and can be replaced with any string. For example,
print "123".join(['a','b','c'])
will print
a123b123c
def SOME_FUNCTION_THAT_TAKES_AN_ARRAY_AS_INPUT (arr):
return str(tuple(arr))
Replace str with unicode if you need to.
SOME_FUNCTION_THAT_TAKES_AN_ARRAY_AS_INPUT = tuple
If your array's items are specifically integers, str(tuple(array)) as suggested in #jboxer's answer will work. For most other types of items, it may be more of a problem, since str(tuple(...)) uses repr, not str -- that's really needed as a default behavior (otherwise printing a tuple with an item such as the string '1, 2' would be extremely confusing, looking just like a string with the two int items 1 and 2!-), but it may or may not be what you want. For example:
>>> array = [0.1, 0.2]
>>> print str(tuple(array))
(0.10000000000000001, 0.20000000000000001)
With floating point numbers, repr emits many more digits than make sense in most cases (while str, if called directly on the numbers, behaves a bit better). So if your items are liable to be floats (as well as ints, which would need no precaution but won't be hurt by this one;-), you might better off with:
>>> print '(%s)' % (', '.join(str(x) for x in array))
(0.1, 0.2)
However, this might produce ambiguous output if some of the items are strings, as I mentioned earlier!
If you know what types of data you're liable to have in the list which you call "array", it would give a better basis on which to recommend a solution.

Categories

Resources