How to concatenate strings into parenthesis in Python - python

In Python I have this loop that e.g. prints some value:
for row in rows:
toWrite = row[0]+","
toWrite += row[1]
toWrite += "\n"
Now this works just fine, and if I print "toWrite" it would print this:
print toWrite
#result:,
A,B
C,D
E,F
... etc
My question is, how would I concatenate these strings with parenthesis and separated with commas, so result of loop would be like this:
(A,B),(C,D),(E,F) <-- the last item in parenthesis, should not contain - end with comma

You'd group your items into pairs, then use string formatting and str.join():
','.join(['({},{})'.format(*pair) for pair in zip(*[iter(rows)] * 2)])
The zip(*[iter(rows)] * 2) expression produces elements from rows in pairs.
Each pair is formatted with '({},{})'.format(*pair); the two values in pair are slotted into each {} placeholder.
The (A,B) strings are joined together into one long string using ','.join(). Passing in a list comprehension is marginally faster than using a generator expression here as str.join() would otherwise convert it to a list anyway to be able to scan it twice (once for the output size calculation, once for building the output).
Demo:
>>> rows = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
>>> ','.join(['({},{})'.format(*pair) for pair in zip(*[iter(rows)] * 2)])
'(A,B),(C,D),(E,F),(G,H)'

Try this:
from itertools import islice, izip
','.join(('(%s, %s)' % (x, y) for x, y in izip(islice(rows, 0, None, 2), islice(rows, 1, None, 2))))
Generator and iterators are adopted here.
See itertools for a reference.

Related

Python integers with trailing 'L' in a list [duplicate]

So I have a list:
['x', 3, 'b']
And I want the output to be:
[x, 3, b]
How can I do this in python?
If I do str(['x', 3, 'b']), I get one with quotes, but I don't want quotes.
In Python 2:
mylist = ['x', 3, 'b']
print '[%s]' % ', '.join(map(str, mylist))
In Python 3 (where print is a builtin function and not a syntax feature anymore):
mylist = ['x', 3, 'b']
print('[%s]' % ', '.join(map(str, mylist)))
Both return:
[x, 3, b]
This is using the map() function to call str for each element of mylist, creating a new list of strings that is then joined into one string with str.join(). Then, the % string formatting operator substitutes the string in instead of %s in "[%s]".
This is simple code, so if you are new you should understand it easily enough.
mylist = ["x", 3, "b"]
for items in mylist:
print(items)
It prints all of them without quotes, like you wanted.
Using only print:
>>> l = ['x', 3, 'b']
>>> print(*l, sep='\n')
x
3
b
>>> print(*l, sep=', ')
x, 3, b
If you are using Python3:
print('[',end='');print(*L, sep=', ', end='');print(']')
Instead of using map, I'd recommend using a generator expression with the capability of join to accept an iterator:
def get_nice_string(list_or_iterator):
return "[" + ", ".join( str(x) for x in list_or_iterator) + "]"
Here, join is a member function of the string class str. It takes one argument: a list (or iterator) of strings, then returns a new string with all of the elements concatenated by, in this case, ,.
You can delete all unwanted characters from a string using its translate() method with None for the table argument followed by a string containing the character(s) you want removed for its deletechars argument.
lst = ['x', 3, 'b']
print str(lst).translate(None, "'")
# [x, 3, b]
If you're using a version of Python before 2.6, you'll need to use the string module's translate() function instead because the ability to pass None as the table argument wasn't added until Python 2.6. Using it looks like this:
import string
print string.translate(str(lst), None, "'")
Using the string.translate() function will also work in 2.6+, so using it might be preferable.
Here's an interactive session showing some of the steps in #TokenMacGuy's one-liner. First he uses the map function to convert each item in the list to a string (actually, he's making a new list, not converting the items in the old list). Then he's using the string method join to combine those strings with ', ' between them. The rest is just string formatting, which is pretty straightforward. (Edit: this instance is straightforward; string formatting in general can be somewhat complex.)
Note that using join is a simple and efficient way to build up a string from several substrings, much more efficient than doing it by successively adding strings to strings, which involves a lot of copying behind the scenes.
>>> mylist = ['x', 3, 'b']
>>> m = map(str, mylist)
>>> m
['x', '3', 'b']
>>> j = ', '.join(m)
>>> j
'x, 3, b'
Using .format for string formatting,
mylist = ['x', 3, 'b']
print("[{0}]".format(', '.join(map(str, mylist))))
Output:
[x, 3, b]
Explanation:
map is used to map each element of the list to string type.
The elements are joined together into a string with , as separator.
We use [ and ] in the print statement to show the list braces.
Reference:
.format for string formatting PEP-3101
I was inspired by #AniMenon to write a pythonic more general solution.
mylist = ['x', 3, 'b']
print('[{}]'.format(', '.join(map('{}'.format, mylist))))
It only uses the format method. No trace of str, and it allows for the fine tuning of the elements format.
For example, if you have float numbers as elements of the list, you can adjust their format, by adding a conversion specifier, in this case :.2f
mylist = [1.8493849, -6.329323, 4000.21222111]
print("[{}]".format(', '.join(map('{:.2f}'.format, mylist))))
The output is quite decent:
[1.85, -6.33, 4000.21]

Permutations using a multidict

I'm trying to put together a code that replaces unique characters in a given input string with corresponding values in a dictionary in a combinatorial manner while preserving the position of 'non' unique characters.
For example, I have the following dictionary:
d = {'R':['A','G'], 'Y':['C','T']}
How would go about replacing all instances of 'R' and 'Y' while producing all possible combinations of the string but maintaining the positions of 'A' and 'C'?
For instance, the input 'ARCY' would generate the following output:
'AACC'
'AGCC'
'AACT'
'AGCT'
Hopefully that makes sense. If anyone can point me in the right directions, that would be great!
Given the dictionary, we can state a rule that tells us what letters are possible at a given position in the output. If the original letter from the input is in the dictionary, we use the value; otherwise, there is a single possibility - the original letter itself. We can express that very neatly:
def candidates(letter):
d = {'R':['A','G'], 'Y':['C','T']}
return d.get(letter, [letter])
Knowing the candidates for each letter (which we can get by mapping our candidates function onto the letters in the pattern), we can create the Cartesian product of candidates, and collapse each result (which is a tuple of single-letter strings) into a single string by simply ''.joining them.
def substitute(pattern):
return [
''.join(result)
for result in itertools.product(*map(candidates, pattern))
]
Let's test it:
>>> substitute('ARCY')
['AACC', 'AACT', 'AGCC', 'AGCT']
The following generator function produces all of your desired strings, using enumerate, zip, itertools.product, a list comprehension and argument list unpacking all of which are very handy Python tools/concepts you should read up on:
from itertools import product
def multi_replace(s, d):
indexes, replacements = zip(*[(i, d[c]) for i, c in enumerate(s) if c in d])
# indexes: (1, 3)
# replacements: (['A', 'G'], ['C', 'T'])
l = list(s) # turn s into sth. mutable
# iterate over cartesian product of all replacement tuples ...
for p in product(*replacements):
for index, replacement in zip(indexes, p):
l[index] = replacement
yield ''.join(l)
d = {'R': ['A', 'G'], 'Y': ['C', 'T']}
s = 'ARCY'
for perm in multi_replace(s, d):
print perm
AACC
AACT
AGCC
AGCT
s = 'RRY'
AAC
AAT
AGC
AGT
GAC
GAT
GGC
GGT
Change ARCY to multiple list and use below code:
import itertools as it
list = [['A'], ['A','G'],['C'],['C','T']]
[''.join(item) for item in it.product(*list)]
or
import itertools as it
list = ['A', 'AG','C', 'CT']
[''.join(item) for item in it.product(*list)]

Not getting what I want using the format function

Ok. I have a CSV, and I'm trying to use the format function to rearrange the order in which the data of the columns prints.
In other words, how can I use the format function to print columns in the order e,d,c instead of the default c,d,e?
Here's what I have so far:
for row in books:
print [item.upper() for item in row]
print [format(item[])
What am I missing here?
Formatting strings
I am not sure what are you asking for, but this may suit your needs:
>>> my_items = ['c', 'd', 'e']
>>> print '{2} {1} {0}'.format(*my_items)
e d c
It uses formatting, which allows you to print items in any order you like. See documentation of format() for more.
Reversing lists
If you want just to reverse order of the array, just provide -1 for "step" part within brackets after list's name:
>>> my_items = ['c', 'd', 'e']
>>> my_items[::-1]
['e', 'd', 'c']
so your code may look like this:
for row in books:
print [item.upper() for item in row[::-1]]
which will print list of uppercase items in a row, but in reversed order.
If you want to change the order of the columns, you can do:
for row in books:
print list(reversed(row)) # Prints the reversed row, as a list
print ', '.join(reversed(row)) # Prints a single string of comma-separated values
print [row[index] for index in (2, 0, 1)] # General order change
print ', '.join(row[index] for index in (2, 0, 1)) # Same thing, but prints a string
Isolating the column order from the input data is a good use for DictWriter.
>>> data = [range(i, i+3) for i in range(5)]
>>> import csv, StringIO
>>> f = StringIO.StringIO()
Create the writer, with fields in the order you need.
>>> writer = csv.DictWriter(f, ('e', 'd', 'c'))
And create some way to make a dict that has those keys, from whatever your input is.
>>> def datamap(row):
... return dict(zip('cde', row))
...
Then it's just a matter of using the csv writer as normal. (writeheader() is just a convenience so we can see what the columns look like, it is by no means mandatory)
>>> writer.writeheader()
>>> for datum in data:
... writer.writerow(datamap(datum))
...
>>> print f.getvalue()
e,d,c
2,1,0
3,2,1
4,3,2
5,4,3
6,5,4
>>>

How to "properly" print a list?

So I have a list:
['x', 3, 'b']
And I want the output to be:
[x, 3, b]
How can I do this in python?
If I do str(['x', 3, 'b']), I get one with quotes, but I don't want quotes.
In Python 2:
mylist = ['x', 3, 'b']
print '[%s]' % ', '.join(map(str, mylist))
In Python 3 (where print is a builtin function and not a syntax feature anymore):
mylist = ['x', 3, 'b']
print('[%s]' % ', '.join(map(str, mylist)))
Both return:
[x, 3, b]
This is using the map() function to call str for each element of mylist, creating a new list of strings that is then joined into one string with str.join(). Then, the % string formatting operator substitutes the string in instead of %s in "[%s]".
This is simple code, so if you are new you should understand it easily enough.
mylist = ["x", 3, "b"]
for items in mylist:
print(items)
It prints all of them without quotes, like you wanted.
Using only print:
>>> l = ['x', 3, 'b']
>>> print(*l, sep='\n')
x
3
b
>>> print(*l, sep=', ')
x, 3, b
If you are using Python3:
print('[',end='');print(*L, sep=', ', end='');print(']')
Instead of using map, I'd recommend using a generator expression with the capability of join to accept an iterator:
def get_nice_string(list_or_iterator):
return "[" + ", ".join( str(x) for x in list_or_iterator) + "]"
Here, join is a member function of the string class str. It takes one argument: a list (or iterator) of strings, then returns a new string with all of the elements concatenated by, in this case, ,.
You can delete all unwanted characters from a string using its translate() method with None for the table argument followed by a string containing the character(s) you want removed for its deletechars argument.
lst = ['x', 3, 'b']
print str(lst).translate(None, "'")
# [x, 3, b]
If you're using a version of Python before 2.6, you'll need to use the string module's translate() function instead because the ability to pass None as the table argument wasn't added until Python 2.6. Using it looks like this:
import string
print string.translate(str(lst), None, "'")
Using the string.translate() function will also work in 2.6+, so using it might be preferable.
Here's an interactive session showing some of the steps in #TokenMacGuy's one-liner. First he uses the map function to convert each item in the list to a string (actually, he's making a new list, not converting the items in the old list). Then he's using the string method join to combine those strings with ', ' between them. The rest is just string formatting, which is pretty straightforward. (Edit: this instance is straightforward; string formatting in general can be somewhat complex.)
Note that using join is a simple and efficient way to build up a string from several substrings, much more efficient than doing it by successively adding strings to strings, which involves a lot of copying behind the scenes.
>>> mylist = ['x', 3, 'b']
>>> m = map(str, mylist)
>>> m
['x', '3', 'b']
>>> j = ', '.join(m)
>>> j
'x, 3, b'
Using .format for string formatting,
mylist = ['x', 3, 'b']
print("[{0}]".format(', '.join(map(str, mylist))))
Output:
[x, 3, b]
Explanation:
map is used to map each element of the list to string type.
The elements are joined together into a string with , as separator.
We use [ and ] in the print statement to show the list braces.
Reference:
.format for string formatting PEP-3101
I was inspired by #AniMenon to write a pythonic more general solution.
mylist = ['x', 3, 'b']
print('[{}]'.format(', '.join(map('{}'.format, mylist))))
It only uses the format method. No trace of str, and it allows for the fine tuning of the elements format.
For example, if you have float numbers as elements of the list, you can adjust their format, by adding a conversion specifier, in this case :.2f
mylist = [1.8493849, -6.329323, 4000.21222111]
print("[{}]".format(', '.join(map('{:.2f}'.format, mylist))))
The output is quite decent:
[1.85, -6.33, 4000.21]

going through a dictionary and printing its values in sequence

def display_hand(hand):
for letter in hand.keys():
for j in range(hand[letter]):
print letter,
Will return something like: b e h q u w x. This is the desired output.
How can I modify this code to get the output only when the function has finished its loops?
Something like below code causes me problems as I can't get rid of dictionary elements like commas and single quotes when printing the output:
def display_hand(hand):
dispHand = []
for letter in hand.keys():
for j in range(hand[letter]):
##code##
print dispHand
UPDATE
John's answer is very elegant i find. Allow me however to expand o Kugel's response:
Kugel's approach answered my question. However i kept running into an additional issue: the function would always return None as well as the output. Reason: Whenever you don't explicitly return a value from a function in Python, None is implicitly returned. I couldn't find a way to explicitly return the hand. In Kugel's approach i got closer but the hand is still buried in a FOR loop.
You can do this in one line by combining a couple of list comprehensions:
print ' '.join(letter for letter, count in hand.iteritems() for i in range(count))
Let's break that down piece by piece. I'll use a sample dictionary that has a couple of counts greater than 1, to show the repetition part working.
>>> hand
{'h': 3, 'b': 1, 'e': 2}
Get the letters and counts in a form that we can iterate over.
>>> list(hand.iteritems())
[('h', 3), ('b', 1), ('e', 2)]
Now just the letters.
>>> [letter for letter, count in hand.iteritems()]
['h', 'b', 'e']
Repeat each letter count times.
>>> [letter for letter, count in hand.iteritems() for i in range(count)]
['h', 'h', 'h', 'b', 'e', 'e']
Use str.join to join them into one string.
>>> ' '.join(letter for letter, count in hand.iteritems() for i in range(count))
'h h h b e e'
Your ##code perhaps?
dispHand.append(letter)
Update:
To print your list then:
for item in dispHand:
print item,
another option without nested loop
"".join((x+' ') * y for x, y in hand.iteritems()).strip()
Use
" ".join(sequence)
to print a sequence without commas and the enclosing brackets.
If you have integers or other stuff in the sequence
" ".join(str(x) for x in sequence)

Categories