Any idea why when I call:
>>> hi = [1, 2]
>>> hi[1]=3
>>> print hi
[1, 3]
I can update a list item by its index, but when I call:
>>> phrase = "hello"
>>> for item in "123":
>>> list(phrase)[int(item)] = list(phrase)[int(item)].upper()
>>> print phrase
hello
It fails?
Should be hELLo
You haven't initialised phrase (The list you were intending to make) into a variable yet. So pretty much you have created a list in each loop, it being the exact same.
If you were intending to actually change the characters of phrase, well that's not possible, as in python, strings are immutable.
Perhaps make phraselist = list(phrase), then edit the list in the for-loop. Also, you can use range():
>>> phrase = "hello"
>>> phraselist = list(phrase)
>>> for i in range(1,4):
... phraselist[i] = phraselist[i].upper()
...
>>> print ''.join(phraselist)
hELLo
>>> phrase = "hello"
>>> list_phrase = list(phrase)
>>> for index in (1, 2, 3):
list_phrase[index] = phrase[index].upper()
>>> ''.join(list_phrase)
'hELLo'
If you prefer one-liner:
>>> ''.join(x.upper() if index in (1, 2, 3) else x for
index, x in enumerate(phrase))
'hELLo'
Another answer, just for fun :)
phrase = 'hello'
func = lambda x: x[1].upper() if str(x[0]) in '123' else x[1]
print ''.join(map(func, enumerate(phrase)))
# hELLo
To make this robust, I created a method: (because I am awesome, and bored)
def method(phrase, indexes):
func = lambda x: x[1].upper() if str(x[0]) in indexes else x[1]
return ''.join(map(func, enumerate(phrase)))
print method('hello', '123')
# hELLo
consider that strings are immutable in python You can't modify existing string can create new.
''.join([c if i not in (1, 2, 3) else c.upper() for i, c in enumerate(phrase)])
list() creates a new list. Your loop creates and instantly discards two new lists on each iteration. You could write it as:
phrase = "hello"
L = list(phrase)
L[1:4] = phrase[1:4].upper()
print("".join(L))
Or without a list:
print("".join([phrase[:1], phrase[1:4].upper(), phrase[4:]]))
Strings are immutable in Python therefore to change it, you need to create a new string.
Or if you are dealing with bytestrings, you could use bytearray which is mutable:
phrase = bytearray(b"hello")
phrase[1:4] = phrase[1:4].upper()
print(phrase.decode())
If indexes are not consecutive; you could use an explicit for-loop:
indexes = [1, 2, 4]
for i in indexes:
L[i] = L[i].upper()
Related
I have
char=str('DOTR')
and
a=range(0,18)
How could I combine them to create a list with:
mylist=['DOTR00','DOTR01',...,'DOTR17']
If I combine them in a for loop then I lose the leading zero.
Use zfill:
>>> string = "DOTR"
>>> for i in range(0, 18):
... print("DOTR{}".format(str(i).zfill(2)))
...
DOTR00
DOTR01
DOTR02
DOTR03
DOTR04
DOTR05
DOTR06
DOTR07
DOTR08
DOTR09
DOTR10
DOTR11
DOTR12
DOTR13
DOTR14
DOTR15
DOTR16
DOTR17
>>>
And if you want a list:
>>> my_list = ["DOTR{}".format(str(i).zfill(2)) for i in range(18)]
>>> my_list
['DOTR00', 'DOTR01', 'DOTR02', 'DOTR03', 'DOTR04', 'DOTR05', 'DOTR06', 'DOTR07', 'DOTR08', 'DOTR09', 'DOTR10', 'DOTR11', 'DOTR12', 'DOTR13', 'DOTR14', 'DOTR15', 'DOTR16', 'DOTR17']
>>>
You can do it using a list comprehension like so:
>>> mylist = [char+'{0:02}'.format(i) for i in a]
>>> mylist
['DOTR00', 'DOTR01', 'DOTR02', 'DOTR03', 'DOTR04', 'DOTR05', 'DOTR06', 'DOTR07', 'DOTR08', 'DOTR09', 'DOTR10', 'DOTR11', 'DOTR12', 'DOTR13', 'DOTR14', 'DOTR15', 'DOTR16', 'DOTR17']
Simply use list comprehension and format:
mylist = ['DOTR%02d'%i for i in range(18)]
Or given that char and a are variable:
mylist = ['%s%02d'%(char,i) for i in a]
You can, as #juanpa.arrivillaga also specify it as:
mylist = ['{}{:02d}'.format(char,i) for i in a]
List comprehension is a concept where you write an expression:
[<expr> for <var> in <iterable>]
Python iterates over the <iterable> and unifies it with <var> (here i), next it calls the <expr> and the result is appended to the list until the <iterable> is exhausted.
can do like this
char = str('DOTR')
a=range(0,18)
b = []
for i in a:
b.append(char + str(i).zfill(2))
print(b)
These commands:
l = ["1\n2"]
print(l)
print
['1\n2']
I want to print
['1
2']
Is it possible when we generate the list outside of the print() command?
A first attempt:
l = ["1\n2"]
print(repr(l).replace('\\n', '\n'))
The solution above doesn't work in tricky cases, for example if the string is "1\\n2" it replaces, but it shouldn't. Here is how to fix it:
import re
l = ["1\n2"]
print(re.sub(r'\\n|(\\.)', lambda match: match.group(1) or '\n', repr(l)))
Only if you are printing the element itself (or each element) and not the whole list:
>>> a = ['1\n2']
>>> a
['1\n2']
>>> print a
['1\n2']
>>> print a[0]
1
2
When you try to just print the whole list, it prints the string representation of the list. Newlines belong to individual elements so get printed as newlines only when print that element. Otherwise, you will see them as \n.
You should probably use this, if you have more than one element
>>> test = ['1\n2', '3', '4\n5']
>>> print '[{0}]'.format(','.join(test))
[1
2,3,4
5]
Try this:
s = ["1\n2"]
print("['{}']".format(s[0]))
=> ['1
2']
In the following i have an array where for each element a string should be added at the start and not append ,how can i do this
a=["Hi","Sam","How"]
I want to add "Hello" at the start of each element so that the output will be
Output:
a=["HelloHi","HelloSam","HelloHow"]
This works for a list of strings:
a = ['Hello'+b for b in a]
and this works for other objects too (uses their strings representation):
a = ['Hello{}'.format(b) for b in a]
Example:
a = ["Hi", "Sam", "How", 1, {'x': 123}, None]
a = ['Hello{}'.format(b) for b in a]
# ['HelloHi', 'HelloSam', 'HelloHow', 'Hello1', "Hello{'x': 123}", 'HelloNone']
a=["Hi","Sam","How"]
a = ["hello" + x for x in a]
print a
or you can use map:
map('Hello{0}'.format,a)
Another option:
>>> def say_hello(foo):
... return 'Hello{}'.format(foo)
...
>>> map(say_hello,['hi','there'])
['Hellohi', 'Hellothere']
There must be an easier way or function to do this code here:
#!/usr/bin/env python
string = "test [*string*] test [*st[ *ring*] test"
points = []
result = string.find("[*")
new_string = string[result+1:]
while result != -1:
points.append(result)
new_string = new_string[result+1:]
result = new_string.find("[*")
print points
Any ideas?
import re
string = "test [*string*] test [*st[ *ring*] test"
points = [m.start() for m in re.finditer('\[', string)]
It looks like you're trying to get the indices in the string that match '[*'...
indices=[i for i in range(len(string)-1) if string[i:i+2] == '[*']
But this output is different than what your code will produce. Can you verify that your code does what you want?
Also note that string is the name of a python module in the standard library -- while it isn't used very often, it's probably a good idea to avoid using it as a variable name. (don't use str either)
>>> indexes = lambda str_, pattern: reduce(
... lambda acc, x: acc + [acc[-1] + len(x) + len(pattern)],
... str_.split(pattern), [-len(pattern)])[1:-1]
>>> indexes('123(456(', '(')
[3, 7]
>>> indexes('', 'x')
[]
>>> indexes("test [*string*] test [*st[ *ring*] test", '[*')
[5, 21]
>>> indexes('1231231','1')
[0, 3, 6]
I have a python function that gets an array called row.
Typically row contains things like:
["Hello","goodbye","green"]
And I print it with:
print "\t".join(row)
Unfortunately, sometimes it contains:
["Hello",None,"green"]
Which generates this error:
TypeError: sequence item 2: expected string or Unicode, NoneType found
Is there an easy way to replace any None elements with ""?
You can use a conditional expression:
>>> l = ["Hello", None, "green"]
>>> [(x if x is not None else '') for x in l]
['Hello', '', 'green']
A slightly shorter way is:
>>> [x or '' for x in l]
But note that the second method also changes 0 and some other objects to the empty string.
You can use a generator expression in place of the array:
print "\t".join(fld or "" for fld in row)
This will substitute the empty string for everything considered as False (None, False, 0, 0.0, ''…).
You can also use the built-in filter function:
>>> l = ["Hello", None, "green"]
>>> filter(None, l)
['Hello', 'green']