Disclaimer: The question how to print a list in python is already covered multiple times, thus, this question does NOT ask HOW to print a list BUT WHETHER a specific way to print a list exists (using the format directive).
The first hit one gets googling how to print a list using format in python is here and it looks like:
print('\n'.join('{}'.format(k) for k in lst))
is the way to go. But I keep wondering if there is a lisp like format directive to do this without the verbose join operation. E.g. in common lisp one would simple write:
(FORMAT T "~%~{~a~%~}" list-i-want-printed)
~{...~} basically means iterate over list
~a basically means to take one argument and print it using its (or the default) print/to-string directive
~% newline
Does such a format directive exist in python?
As a more thorough example why I'd like to use such directive:
Given you have 3 lists you want to print below each other. The lisp FORMAT would allow:
(FORMAT T "~{~a~}~%~{~a~}~%~{~a~}~%" list-1 list-2 list-3)
whereas the python solution would look like:
print(''.join('{}'.format(k) for k in lsta) + '\n' + ''.join('{}'.format(k) for k in lstb) + '\n' + ''.join('{}'.format(k) for k in lstc))
not quite as refined.
I think the basic answer is "No", but you can refine your example a bit:
print( ' '.join( '{}'.format(k) for k in lsta+lstb+lstc ) )
No newlines. If I wanted a newline after each list I'd do
for lst in (lsta,lstb,lstc):
print( ' '.join( '{}'.format(k) for k in lst ) )
Related
I was trying to solve up a problem that was going on cause my IDE could not retain a sequence of numbers cause of the range function which works as so.
And i made a Previous question about it so this is a follow-up to the question. Here's my list comment on the previous question.
I actually made some adjustments by adding a line; 'My_list = list(range(100)) before applying your code so it actually worked. But it combines the answers without commas, for example 10 does this '0123456789' instead of '0,1,2,3,4,5,.....8,9'. any suggestions?
I decided to post this question not to allow the other question go out of context (as i was advised to).
Any suggestions?
You need to understand how strings works in Python.
Strings are constants (literals) kept in a closed bucket. In official docs you can find that "Strings are immutable sequences of Unicode code points".
But programmers need to change or manipulate text in a programmable way. In your case you want:
"[x1][space][comma][x2][comma]...[xn][space][comma]"
where "xn" is a number, and " ," is constant.
In order to achieve this, in a programmable way, programmers can use "masks" to tell the software where they want to place their changes. One can use string format operators:
"%d , %f" %(my_first_integer, my_float)
[0][1][2][3][4][\0]
# Hey Python, return a string, using the above template,
# but place useful stuff where you find magic keywords.
Which means:
Create a 6 positions sequence;
In [0], place my_integer of type int converted into chr;
In [1], copy " ";
In [2], copy ",".
In [3], copy " ";
In [4], place my_float of type float converted into chr;
In [5], place "\0" so the string is over. (Automatically placed in Python)
There are other ways to do this, i.e., the string object has a handy method called formatto handle this construction:
my_integer = 2
my_string = "{0}*pi = {1}".format(my_integer, my_integer*3.14)
print(my_string)
# 2*pi = 6.28
The programmer will achieve the same final result using one or another startegy.
In Python, as well as in other languages, one can combine strings, concatenate, get sub-strings and so on, using specific methods and/or operators.
In order to keep readability you maybe (I guess) want to place each value in a line. In strings you can use special characters like \n for new lines.
my_list = list(range(100))
# ... useful code here and there ...
with open("output.txt", "w") as o:
o.write("My list:\n")
o.write("\tSize: {0}\n\n".format(len(my_list)))
o.write("\t----start----\n")
for i in range(len(my_list)):
o.write("%d\n" % my_list[i])
o.write("\n\t----end----\n")
# That writes:
# My list:
# Size: 100
#
# ----start----
# 0
# 1
# 2
# 3
...
# 99
#
# ----end----
Remember, this is not a comprehensive guide, but a layman one. I'm skipping a lot of boring words and technical details that you'll better find in Python books and courses.
You just need to insert a comma after printing each number:
my_list = list(range(100))
with open("output.txt", "w") as o:
for i in range(len(my_list)):
o.write("%d," % my_list[i]) # Here, after '%d' you can place a comma, or any text you want
Problem:
I need to create a complex string from different parts (nbsp = u'\xa0', data['text'], delimeter).
I know 3 common solutions:
res = '*{nbsp}{nbsp}{nbsp}{nbsp}{0}*{1}'.format(data['text'], delimeter, nbsp=nbsp) # seems unicode error-prone way
res = '*' + 4 * nbsp + data['text'] + '*' + delimeter
res = ''.join(['*', 4 * nbsp, data['text'], '*', delimeter])
There is another way with old % string formatting way but it looks like it becomes a legacy way.
So which one is most pythonic or may be preferable for this certain case?
Your first approach can be improved by uniformly using keyword arguments.
u'*{nbsps}{text}*{delimiter}'.format(nbsps=4*nbsp,
text=data['text'],
delimiter=delimiter)
The format string makes it clear that it contains three more complex blocks, each of which is defined in the same way in the arguments to unicode.format.
"Pythonic", as I understand it, means "can be deciphered in no time after a year of not seeing the code". I would throw the following hat in the ring:
res = "*%s%s*%s" % (4*nbsp, str(data["text"]), delimiter)
even if you consider it legacy, because it is understandable. Read it and compare it with decompiling the above suggestions.
Third one is not good solution but first two is good enough. But I prefer mixing it and trying this :
str("*"+4*"{0}"+"{1}"+"*"+"{2}").format(nbsp, data['text'], delimeter)
I am trying to print a list of lists in python like so:
for location in latLongList:
print ' '.join(map(str, location))
This prints out:
40.0349216312 -75.1900864349 Paved 4 0.156150432289
39.9531308619 -75.1629612614 Paved 3 0.170932927052
39.9610355788 -75.1725011285 Paved 0.17296824247
39.9788367755 -75.2123945669 Paved 0.196740550111
39.9467944475 -75.2092212039 Paved 33 0.210834020854
39.94626513 -75.2089212417 Paved 5 0.210899309368
39.9373184367 -75.2341880089 Grass 0.236747322815
39.9413269464 -75.2383849209 0.238056333485
This works fine but I wanted to exclude the last number in each line (which is the last number in each sublist). I also wanted to be able to allow the user to specify the number of lines to be printed. They input that number through the command line and it is stored in a variable called sizeOfList. Would there be an easy way to do this in python? Any help would be greatly appreciated!
You could use the built-in function enumerate to get the index of each location in latLongList, and then print only locations whose index is less than the number desired by the user (sizeOfList). Then, in order to exclude the last item in each sublist (each location), you could take a slice of the sublist up to, but not including, the last item (which is at index -1).
for i, location in enumerate(latLongList):
if i < sizeOfList:
print ' '.join(map(str, location[:-1]))
#Hackaholic introduced an improvement to this method, which makes the code more concise and potentially much faster (due to iteration over fewer locations):
for location in latLongList[:sizeOfList]:
print ' '.join(map(str, location[:-1]))
Here, only the items up to the number desired by the user (sizeOfList) are taken from latLongList. There is no longer a need for enumerate.
You could do something like this:
# this import needs to be first
from __future__ import print_function
for location in latLongList[:sizeOfList]:
print(*location[:-1])
The __future__ import makes print a function, so you can do print(*foo). That's like print(foo[0], foo[1], ...).
First, to print everything but the last element, you slice the list to include everything but its last element: location[:-1]. (Slicing is explained in the tutorial in Using Python as a Calculator; for full details see Sequence Types in the library reference.)
Then, to stop after a certain number of lines, you slice the list of lines: latLongList[:sizeOfList].
So:
for location in latLongList[:sizeOfList]:
print ' '.join(map(str, location[:-1]))
If the list weren't actually a list, but an iterator (or if you were writing generic code that needed to work with both), or if you were worried about the memory waste in making a copy of part of the list (say because you want the first 200 million lines), you could use islice, which solves both of those problems:
from itertools import islice
for location in islice(latLongList, sizeOfList):
print ' '.join(map(str, location[:-1]))
Better to try like this:
for location in latLongList[:sizeOfList]:
print ' '.join(map(str, location[:-1]))
This should solve both problems:
print '\n'.join('{} {} {}'.format(*location) for location in latLongList[:sizeOfList])
This solution is pretty Pythonic. Using str.format() eliminates the need to convert everything to strings by using map(str, ) (str.format() does this automatically for you). Additionally, there is no need to slice the sublist for each location to eliminate the last element, as str.join() ignores the rest of the list automatically. Lastly, it reduces the number of calls to print from sizeOfList times to once. And the str.join() operation is fast because it is joining an iterator instead of a list.
Enjoy!
I am trying to use the Abaqus (a commercial FEA code) scripting interface to generate FE models, although my question is relating to Python specifically, but a bit of background on why I am trying to do this.
Abaqus has a built in boolean merge operation that requires the following syntax to be used:
a.InstanceFromBooleanMerge(name='name_string', instances=(
a.instances['string1'], a.instances['string2'],
a.instances['string3'], ), originalInstances=SUPPRESS,
domain=GEOMETRY)
The 'instances' parameter is specified as a tuple where each element is of the format
a.instances['string1']
I am trying to make it so that the number of elements within this tuple, and obviously the names within it are scriptable. Currently I have code which looks like:
my_list = []
for i in range(4):
name = str('a.instances[\'')+str('name_')+str(i)+str('\']')
my_list.append(name)
my_list = tuple(my_list)
print my_list
However, this gives:
("a.instances['name_0']", "a.instances['name_1']", "a.instances['name_2']",
a.instances['name_3']")
I have tried using lstrip and rstrip to remove the " characters but to no avail. Is there a way of generating a tuple of arbitrary length where the elements are not enclosed in inverted commas? The format is specified by the Abaqus interface, so there is no alternative format that can be used.
Many Thanks
You're close, try:
for i in range(4):
val = a.instances["name_"+str(i)]
my_list.append(val)
You can make this even shorter using a generator expression:
my_list = tuple(a.instances["name_"+str(i)] for i in range(4))
Those characters will be printed out simply because you're printing out a tuple - that means strings will be quoted, so you can see the difference between (123,) and ("123",). If you want to have it without quotes, construct the output yourself:
def make_tuple_of(n):
return '(' + ', '.join("a.instances['name_" + str(i) + "']" for i in range(n)) + ')'
Edit: I thought you actually wanted to generate the code itself, not create tuple in the current code. If generating a tuple in current code is what you actually want to do, just use tuple(a.instances['name_' + str(i)] for i in range(n))
Edit2: Actually, you could check the library you're working with. Unless it specifically tests for tuples for some reason, it accept lists just fine, since the interface for both is pretty much the same. If it does, you could just pass it [a.instances['name_' + str(i)] for i in range(n)] as a parameter and be done.
I have a text box in wxPython that takes the output of dictionary.items() and displays it to the user as items are added to the dictionary. However, the raw data is very ugly, looking like
[(u'BC',45)
(u'CHM',25)
(u'CPM',30)]
I know dictionary.items() is a list of tuples, but I can't seem to figure out how to make a nice format that is also compatible with the SetValue() method of wxPython.
I've tried iterating through the list and tuples. If I use a print statement, the output is fine. But when I replace the print statement with SetValue(), it only seems to get the last value of each tuple, rather than both items in the tuple.
I've also tried creating a string and passing that string to SetValue() but, again, I can only get one item in the tuple or the other, not both.
Any suggestions?
Edit: Yes, I am passing the results of the dictionary.items() to a text field in a wxPython application. Rather than having the results like above, I'm simply looking for something like:
BC 45
CHM 25
CMP 30
Nothing special, just simply pulling each value from each tuple and making a visual list.
I have tried making a string format and passing that to SetValue() but it gets hung up on the two values in the tuple. It will either double print each string and add the integers together or it simply returns the integer, depending on how I format it.
There is no built-in dictionary method that would return your desired result.
You can, however, achieve your goal by creating a helper function that will format the dictionary, e.g.:
def getNiceDictRepr(aDict):
return '\n'.join('%s %s' % t for t in aDict.iteritems())
This will produce your exact desired output:
>>> myDict = dict([(u'BC',45), (u'CHM',25), (u'CPM',30)])
>>> print getNiceDictRepr(myDict)
BC 45
CHM 25
CPM 30
Then, in your application code, you can use it by passing it to SetValue:
self.textCtrl.SetValue(getNiceDictRepr(myDict))
Maybe the pretty print module will help:
>>> import pprint
>>> pprint.pformat({ "my key": "my value"})
"{'my key': 'my value'}"
>>>
text_for_display = '\n'.join(item + u' ' + unicode(value) for item, value in my_dictionary.items())
use % formatting (known in C as sprintf), e.g:
"%10s - %d" % dict.items()[0]
Number of % conversion specifications in the format string should match tuple length, in the dict.items() case, 2. The result of the string formatting operator is a string, so that using it as an argument to SetValue() is no problem. To translate the whole dict to a string:
'\n'.join(("%10s - %d" % t) for t in dict.items())
The format conversion types are specified in the doc.
That data seems much better displayed as a Table/Grid.
I figured out a "better" way of formatting the output. As usual, I was trying to nuke it out when a more elegant method will do.
for key, value in sorted(self.dict.items()):
self.current_list.WriteText(key + " " + str(self.dict[key]) + "\n")
This way also sorts the dictionary alphabetically, which is a big help when identifying items that have already been selected or used.