Python concatenate list - python

I'm new to python and this is just to automate something on my PC. I want to concatenate all the items in a list. The problem is that
''.join(list)
won't work as it isn't a list of strings.
This site http://www.skymind.com/~ocrow/python_string/ says the most efficient way to do it is
''.join([`num` for num in xrange(loop_count)])
but that isn't valid python...
Can someone explain the correct syntax for including this sort of loop in a string.join()?

You need to turn everything in the list into strings, using the str() constructor:
''.join(str(elem) for elem in lst)
Note that it's generally not a good idea to use list for a variable name, it'll shadow the built-in list constructor.
I've used a generator expression there to apply the str() constructor on each and every element in the list. An alternative method is to use the map() function:
''.join(map(str, lst))
The backticks in your example are another spelling of calling repr() on a value, which is subtly different from str(); you probably want the latter. Because it violates the Python principle of "There should be one-- and preferably only one --obvious way to do it.", the backticks syntax has been removed from Python 3.

Here is another way (discussion is about Python 2.x):
''.join(map(str, my_list))
This solution will have the fastest performance and it looks nice and simple imo. Using a generator won't be more efficient. In fact this will be more efficient, as ''.join has to allocate the exact amount of memory for the string based on the length of the elements so it will need to consume the whole generator before creating the string anyway.
Note that `` has been removed in Python 3 and it's not good practice to use it anymore, be more explicit by using str() if you have to eg. str(num).

just use this, no need of [] and use str(num):
''.join(str(num) for num in xrange(loop_count))
for list just replace xrange(loop_count) with the list name.
example:
>>> ''.join(str(num) for num in xrange(10)) #use range() in python 3.x
'0123456789'

If your Python is too old for "list comprehensions" (the odd [x for x in ...] syntax), use map():
''.join(map(str, list))

Related

Python insert a line break in a string after character "X"

What is the python syntax to insert a line break after every occurrence of character "X" ? This below gave me a list object which has no split attribute error
for myItem in myList.split('X'):
myString = myString.join(myItem.replace('X','X\n'))
myString = '1X2X3X'
print (myString.replace ('X', 'X\n'))
You can simply replace X by "X\n"
myString.replace("X","X\n")
Python 3.X
myString.translate({ord('X'):'X\n'})
translate() allows a dict, so, you can replace more than one different character at time.
Why translate() over replace() ? Check translate vs replace
Python 2.7
myString.maketrans('X','X\n')
A list has no split method (as the error says).
Assuming myList is a list of strings and you want to replace 'X' with 'X\n' in each once of them, you can use list comprehension:
new_list = [string.replace('X', 'X\n') for string in myList]
Based on your question details, it sounds like the most suitable is str.replace, as suggested by #DeepSpace. #levi's answer is also applicable, but could be a bit of a too big cannon to use.
I add to those an even more powerful tool - regex, which is slower and harder to grasp, but in case this is not really "X" -> "X\n" substitution you actually try to do, but something more complex, you should consider:
import re
result_string = re.sub("X", "X\n", original_string)
For more details: https://docs.python.org/2/library/re.html#re.sub

Why am I getting a syntax error for this conditional statement?

I've recently been practicing using map() in Python 3.5.2, and when I tried to run the module it said the comma separating the function and the iterable was a SyntaxError. Here's the code:
eng_swe = {"merry":"god", "christmas":"jul", "and":"och", "happy":"gott",
"new":"nytt", "year":"år"}
def map_translate(l):
"""Translates English words into Swedish using the dictionary above."""
return list(map(lambda x: eng_swe[x] if x in eng_swe.keys(), l))
I noticed that if I eliminate the conditional statement like this:
return list(map(lambda x: eng_swe[x], l))
it works fine, but it sacrifices the ability to avoid attempting to add items to the list that aren't in the dictionary. Interestingly enough, there also weren't any problems when I tried using a conditional statement with reduce(), as shown here:
from functools import reduce
def reduce_max_in_list(l):
"""Returns maximum integer in list using the 'reduce' function."""
return reduce(lambda x, y: x if x > y else y, l)
Yes, I know I could do the exact same thing more cleanly and easily with a list comprehension, but I consider it worth my time to at least learn how to use map() correctly, even if I end up never using it again.
You're getting the SyntaxError because you're using a conditional expression without supplying the else clause which is mandatory.
The grammar for conditional expressions (i.e if statements in an expression form) always includes an else clause:
conditional_expression ::= or_test ["if" or_test "else" expression]
^^
In your reduce example you do supply it and, as a result, no errors are being raised.
In your first example, you don't specify what should be returned if the condition isn't true. Since python can't yield nothing from an expression, that is a syntax error. e.g:
a if b # SyntaxError.
a if b else c # Ok.
You might argue that it could be useful to implicitly yield None in this case, but I doubt that a proposal of that sort would get any traction within the community... (I wouldn't vote for it ;-)
While the others' explanations of why your code is causing a SyntaxError are completely accurate, the goal of my answer is to aid you in your goal "to at least learn how to use map() correctly."
Your use of map in this context does not make much sense. As you noted in your answer it would be much cleaner if you used a list comprehension:
[eng_swe[x] for x in l if x in eng_swe]
As you can see, this looks awfully similar to your map expression, minus some of the convolution. Generally, this is a sign that you're using map incorrectly. map(lambda... is pretty much a code smell. (Note that I am saying this as an ardent supporter of the use of map in Python. I know many people think it should never be used, but I am not one of those people, as long as it is used properly.)
So, you might be wondering, what is an example of a good time to use map? Well, one use case I can think of off the top of my head is converting a list of strs to ints. For example, if I am reading a table of data stored in a file, I might do:
with open('my_file.txt', 'r') as f:
data = [map(int, line.split(' ')) for line in f]
Which would leave me with a 2d-array of ints, perfect for further manipulation or analysis. What makes this a better use of map than your code is that it uses a built-in function. I am not writing a lambda expressly to be used by map (as this is a sign that you should use a list comprehension).
Getting back to your code, however... if you want to write your code functionally, you should really be using filter, which is just as important to know as map.
map(lambda x: eng_swe[x], filter(lambda x: eng_swe.get(x), l))
Note that I was unable to get rid of the map(lambda... code smell in my version, but at least I broke it down into smaller parts. The filter finds the words that can be translated and the map performs the actual translation. (Still, in this case, a list comprehension is probably better.) I hope that this explanation helps you more than it confuses you in your quest to write Python code functionally.

exec in Python 3

To take the number of test cases and output all the input numbers, I can do the following in Python 2.5
exec"print input();"*input()
How to do it in Python 3, in shortest possible way?
Your obfuscated code works just fine in Python 3 too, once you have adapted for the changes, which can trivially be done by running the code through 2to3.
exec("print(input());"*eval(input()))
(Although eval should in this case be replaced with int() as that's what you want.)
Obviously, this is all ridicolous, why are you using exec and multiplication of strings instead of loops?
for ignored in range(int(input())):
print(input())
You can also do it with a list expression:
[print(input()) for _ in range(int(input()))]
Although most people would say (and I would agree) that using list expressions for it's side effects or to loop is generally bad form. List expressions should be used to create lists.
This is a piece of clear and self-documenting code that does the same:
num_integers = int(input('How many integers do you want to input? '))
for x in range(num_integers):
print(input('Integer {}: '.format(x)))
Is there a reason you can't use a loop?
for _ in xrange(input()):
print input()
exec, like print, is a function call in Python 3. Wrap the string in parentheses.

simple python list comprehension question

i am trying to select the elements of a list without the very first element. the following code works but it kinda look ugly to me
[s[i] for i in range(len(s)) if i>0]
is there a better way to write it? thanks
Use the slicing notation:
s[1:]
Alternatively, you can avoid copying the list thus:
itertools.islice(s, 1, None)
The result isn't a list — it doesn't support random access, for instance — but you can pass it to anything that accepts an iterator.
Wouldn't s[1:] be correct?

Creating a generator expression from a list in python

What is the best way to do the following in Python:
for item in [ x.attr for x in some_list ]:
do_something_with(item)
This may be a nub question, but isn't the list comprehension generating a new list that we don't need and just taking up memory? Wouldn't it be better if we could make an iterator-like list comprehension.
Yes (to both of your questions).
By using parentheses instead of brackets you can make what's called a "generator expression" for that sequence, which does exactly what you've proposed. It lets you iterate over the sequence without allocating a list to hold all the elements simultaneously.
for item in (x.attr for x in some_list):
do_something_with(item)
The details of generator expressions are documented in PEP 289.
Why not just:
for x in some_list:
do_something_with(x.attr)
This question is tagged functional-programming without an appropriate answer, so here's a functional solution:
from operator import itemgetter
map(do_something_with, map(itemgetter('attr'), some_list))
Python 3's map() uses an iterator, but Python 2 creates a list. For Python 2 use itertools.imap() instead.
If you're returning some_list, you can simplify it further using a generator expression and lazy evaluation :
def foo(some_list):
return (do_something_with(item.attr) for item in some_list)

Categories

Resources