Does Python have a function to neatly build a string that looks like this:
Bob 100 Employee Hourly
Without building a string like this:
EmployeeName + ' ' + EmployeeNumber + ' ' + UserType + ' ' + SalaryType
The function I'm looking for might be called a StringBuilder, and look something like this:
stringbuilder(%s,%s,%s,%s, EmployeeName, EmployeeNumber, UserType, SalaryType, \n)
Normally you would be looking for str.join. It takes an argument of an iterable containing what you want to chain together and applies it to a separator:
>>> ' '.join((EmployeeName, str(EmployeeNumber), UserType, SalaryType))
'Bob 100 Employee Hourly'
However, seeing as you know exactly what parts the string will be composed of, and not all of the parts are native strings, you are probably better of using format:
>>> '{0} {1} {2} {3}'.format(EmployeeName, str(EmployeeNumber), UserType, SalaryType)
'Bob 100 Employee Hourly'
Your question is about Python 2.7, but it is worth note that from Python 3.6 onward we can use f-strings:
place = 'world'
f'hallo {place}'
'hallo world'
This f prefix, called a formatted string literal or f-string, is described in the documentation on lexical analysis
You have two options here:
Use the string .join() method: " ".join(["This", "is", "a", "test"])
Use the percent operator to replace parts of a string: "%s, %s!" % ("Hello", "world")
As EmployeeNumber is a int object , or may you have may int amount your variables you can use str function to convert them to string for refuse of TypeError !
>>> ' '.join(map(str,[EmployeeName, EmployeeNumber,UserType , SalaryType]))
'Bob 100 Employee Hourly'
Python has two simple ways of constructing strings:
string formatting as explained here: https://docs.python.org/2/library/string.html
>>> '{0}, {1}, {2}'.format('a', 'b', 'c')
'a, b, c'
and the old style % operator
https://docs.python.org/2.7/library/stdtypes.html#string-formatting
>>> print '%(language)s has %(number)03d quote types.' % \
... {"language": "Python", "number": 2}
Python has 002 quote types.
Related
Code:
def group_list(group, users):
members = str(users).split()
return group + ":" + str(members)
print(group_list("Marketing", ["Mike", "Karen", "Jake", "Tasha"]))
print(group_list("Engineering", ["Kim", "Jay", "Tom"]))
print(group_list("Users", ""))
Actual output:
Marketing:["['Mike',", "'Karen',", "'Jake',", "'Tasha']"]
Engineering:["['Kim',", "'Jay',", "'Tom']"]
Users:[]
How can I achieve the following desired output instead?
Marketing: Mike, Karen, Jake, Tasha
Engineering: Kim, Jay, Tom
Users:
here is what you are probably looking for:
def group_list(group, users):
users_string = ", ".join(users)
return "{}: {}".format(group, users_string)
print(group_list("Marketing", ["Mike", "Karen", "Jake", "Tasha"]))
print(group_list("Engineering", ["Kim", "Jay", "Tom"]))
print(group_list("Users", ""))
You can join items of arrays easily using join. I prefer building strings using str.format instead of concatenate them using the "+" operator.
str.format: https://docs.python.org/3.4/library/string.html#formatstrings
str.join: https://docs.python.org/3.4/library/stdtypes.html#str.join
In the group_list function you've written, users is a list, so running str(users) converts the standard list format (with brackets) into a string, which is then separated by spaces with .split() (which is meant to split a string into a list). What you want to do is use the .join() method to join all the elements in your input list into a single string
Try this:
def group_list(group, users):
# Join each element of users, separated by ', '
output = group + ': ' + ', '.join(users)
return output
You probably want this. I will give a short summary of what this does.
def group_list(group, users):
return group + ": " + ', '.join(users)
print(group_list("Marketing", ["Mike", "Karen", "Jake", "Tasha"]))
print(group_list("Engineering", ["Kim", "Jay", "Tom"]))
print(group_list("Users", ""))
Displays:
Marketing: Mike, Karen, Jake, Tasha
Engineering: Kim, Jay, Tom
Users:
Explanation:
', '.join(users)
Is used to join a series of strings from the list users with a spacer, in this case a comma followed by a space.
Why did your code not work?
members = str(users).split()
return group + ":" + str(members)
str(users) returns the str representation of a list which means it literally returns a string that looks similar to the following (notice that the string has literal quotes embedded within the string and has square brackets embedded, as well:
"['Mike', 'Karen', 'Jake', 'Tasha']"
When you call .split() on this result, the default behavior of .split() is to split on whitespace and then return a list. Which means we get back something that looks like this:
["['Mike',", "'Karen',", "'Jake',", "'Tasha']"]
We see that this is a list and is surrounded by square brackets and that the list contains a bunch of short str objects:
"['Mike',"
"'Karen',"
"'Jake',"
"'Tasha']"
The next thing that happens in your code is that we try to convert the members list into a str by using str(members) to get the string representation of the members list.
I'd like to specify a string with both line continuation and catenation characters. this is really useful if I'm echoing a bunch of related values. Here is a simple example with only two parameters:
temp = "here is\n"\
+"\t{}\n"\
+"\t{}".format("foo","bar")
print(temp)
here's what I get:
here is
{}
foo
And here is what I expect:
here is
foo
bar
What gives?
You can try something like this :
temp = ("here is\n"
"\t{}\n"
"\t{}".format("foo","bar"))
print(temp)
Or like :
# the \t have been replaced with
# 4 spaces just as an example
temp = '''here is
{}
{}'''.format
print(temp('foo', 'bar'))
vs. what you have:
a = "here is\n"
b = "\t{}\n"
c = "\t{}".format("foo","bar")
print( a + b + c)
str.format is called before your strings are concatenated. Think of it like 1 + 2 * 3, where the multiplication is evaluated before the addition.
Just wrap the whole string in parentheses to indicate that you want the strings concatenated before calling str.format:
temp = ("here is\n"
+ "\t{}\n"
+ "\t{}").format("foo","bar")
Python in effect sees this:
Concatenate the result of
"here is\n"
with the resuslt of
"\t{}\n"
with the result of
"\t{}".format("foo","bar")
You have 3 separate string literals, and only the last one has the str.format() method applied.
Note that the Python interpreter is concatenating the strings at runtime.
You should instead use implicit string literal concatenation. Whenever you place two string literals side by side in an expression with no other operators in between, you get a single string:
"This is a single" " long string, even though there are separate literals"
This is stored with the bytecode as a single constant:
>>> compile('"This is a single" " long string, even though there are separate literals"', '', 'single').co_consts
('This is a single long string, even though there are separate literals', None)
>>> compile('"This is two separate" + " strings added together later"', '', 'single').co_consts
('This is two separate', ' strings added together later', None)
From the String literal concatenation documentation:
Multiple adjacent string or bytes literals (delimited by whitespace), possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation. Thus, "hello" 'world' is equivalent to "helloworld".
When you use implicit string literal concatenation, any .format() call at the end is applied to that whole, single string.
Next, you don't want to use \ backslash line continuation. Use parentheses instead, it is cleaner:
temp = (
"here is\n"
"\t{}\n"
"\t{}".format("foo","bar"))
This is called implicit line joining.
You might also want to learn about multiline string literals, where you use three quotes at the start and end. Newlines are allowed in such strings and remain part of the value:
temp = """\
here is
\t{}
\t{}""".format("foo","bar")
I used a \ backslash after the opening """ to escape the first newline.
The format function is only being applied to the last string.
temp = "here is\n"\
+"\t{}\n"\
+"\t{}".format("foo","bar")
Is doing this:
temp = "here is\n" + "\t{}\n"\ + "\t{}".format("foo","bar")
The key is that the .format() function is only happening to the last string:
"\t{}".format("foo","bar")
You can obtain the desired result using parentheses:
temp = ("here is\n"\
+"\t{}\n"\
+"\t{}").format("foo","bar")
print(temp)
#here is
# foo
# bar
What's the difference between a normal string and a string formatted by '%s', because their results are different, like the following:
# It's ok
>>> "{%s}" % ' and '.join(['nice','good','perfect'])
'{nice and good and perfect}'
# It's not ok
>>> "{' and '}".join(['nice','good','perfect'])
"nice{' and '}good{' and '}perfect"
Your first example,
"{%s}"%' and '.join(['nice','good','perfect'])
joins the list with the given string, ' and ' then puts that in place of the %s
Your second example,
"{' and '}".join(['nice','good','perfect'])
joins the list with the given string, {' and '}. So as you can see, these are two completely different operations, which is why you get a different output.
Change the code as
"{" + " and ".join(['nice','good','perfect']) + "}"
Output:
'{nice and good and perfect}'
My code looks like this:
name = Joe
print "Hello", name, "!"
My output looks like:
Hello Joe !
How do I remove the space between Joe and !?
There are several ways of constructing strings in python. My favorite used to be the format function:
print "Hello {}!".format(name)
You can also concatenate strings using the + operator.
print "Hello " + name + "!"
More information about the format function (and strings in general) can be found here:
https://docs.python.org/2/library/string.html#string.Formatter.format
6 Years Later...
You can now use something called f-Strings if you're using python 3.6 or newer. Just prefix the string with the letter f then insert variable names inside some brackets.
print(f"Hello {name}")
a comma after print will add a blank space.
What you need to do is concatenate the string you want to print; this can be done like this:
name = 'Joe'
print 'Hello ' + name + '!'
Joe must be put between quotes to define it as a string.
>>> print (name)
Joe
>>> print('Hello ', name, '!')
Hello Joe !
>>> print('Hello ', name, '!', sep='')
Hello Joe!
You can also use printf style formatting:
>>> name = 'Joe'
>>> print 'Hello %s !' % name
Hello Joe !
One other solution would be to use the following:
Print 'Hello {} !'.format(name.trim())
This removes all the leading and trailing spaces and special character.
So I have the following dict (the reason it's a dict and not a list is due to the output of the queryparams-parser django package parsing POST values:
doctor_times = {
'1': {
'id': 'ABC',
},
'2': {
'id': 'DEF',
},
}
The plan is to merge these to a string such as "'ABC', 'DEF'" for which I thought the following code would do:
doctorcodes = ', '.join("'%s'" % [str(doctor_times[k]['id']) for k in doctor_times.keys()])
However this results in:
"[, ', A, B, C, ', ,, , ', D, E, F, ', ]"
If I remove the '%s' % component however it works fine, but I do need them wrapped individually in quotes.
The problem with your code is that, you are passing the entire list to '%s' % part. Instead move it only to the string part like this.
print ', '.join(['%s' % str(doctor_times[k]['id']) for k in doctor_times.keys()])
and you don't need to format the data to str again with %s. So, it becomes like this
print ', '.join(str(doctor_times[k]['id']) for k in doctor_times.keys())
This could be further simplified like this
print ", ".join(str(v['id']) for v in doctor_times.values())
I think you may want:
", ".join(repr(v["id"]) for v in doctor_times.values())
This will join the values in an arbitrary order though. If you want the order to be consistent (always "'ABC', 'DEF'" and never "'DEF', 'ABC'"), you may instead need to sort the dictionary items, rather than just iterating over the values directly:
", ".join(repr(v["id"]) for k, v in sorted(doctor_times.items()))
There is one more potential issue with this code. If some of your strings have single quote characters in them (and no double quote characters), their repr will use double quotes, rather than single ones. If a string includes both single and double quotes, the single quote characters will be escaped with \. If the joined string needs to follow some specific convention (such as the rules of a programming language or a data protocol), you may need to use your own escaping code, rather than relying on repr.
You may take a more generic approach by nesting the call to dict.values on the values of the dictionary. What you have is a two depth nested dictionary, but arbitrary depth, the following solution can easily be adopted
>>> ','.join(str(e[0]) for e in map(dict.values, doctor_times.values()))
'ABC,DEF'
or if you prefer itertools
>>> from itertools import imap, chain
>>> ', '.join(map(str, chain.from_iterable(imap(dict.values, doctor_times.values()))))
'ABC, DEF'