This question already has answers here:
How to convert strings numbers to integers in a list?
(4 answers)
Closed 6 years ago.
Given this list:
>>> a = "123DJY65TY"
>>> list(a)
['1','2','3','D','J','Y','6','5','T','Y']
How can I produce a list where integers are not treated as strings? Like this:
[1,2,3,'D','J','Y',6,5,'T','Y']
You can use list comprehension and str.isdigit to convert each character that is a digit:
>>> a = "123DJY65TY"
>>> [int(x) if x.isdigit() else x for x in a]
[1, 2, 3, 'D', 'J', 'Y', 6, 5, 'T', 'Y']
You can convert all strings in a list containing only digits this way, using map() and str.isdigit():
a = map(lambda char: int(char) if char.isdigit() else char, list(a))
For example:
In [3]: a = map(lambda char: int(char) if char.isdigit() else char, list(a))
In [4]: a
Out[4]: [1, 2, 3, 'D', 'J', 'Y', 6, 5, 'T', 'Y']
#niemmi's solution using list comprehensions is probably a better approach given that we start with a string, not a list.
Related
I have a list of strings and variables. For example:
['oz_', A, 'ab'], where A is a list and I don't want anything to happen to it.
And I want to convert it in:
['o','z','_', A, 'a', 'b']
A is a list, so I don't want anything to change it. How can I do this?
You'll need to iterate over each element and turn it into a list if it's a string, but otherwise leave it as a variable and append it.
source = ['oz_', A, 'ab']
result = []
for name in source:
if isinstance(name, str):
result += name
else:
result.append(name)
Note: Use isinstance(name, basetring) for Python2.x if you want to account for other types of string like unicode.
Updated now that we know A shall not be altered.
A = []
seq = ['oz_', A, 'ab']
res = []
for elt in seq:
if isinstance(elt, str):
for e in list(elt):
res.append(e)
else:
res.append(elt)
print(res)
output:
['o', 'z', '_', [], 'a', 'b']
Obligatory one-liner:
>>> A = []
>>> seq = ['oz_', A, 'ab']
>>> [value for values in seq
... for value in (values if isinstance(values, str)
... else [values])]
['o', 'z', '_', [], 'a', 'b']
For converting a list of strings into a list of character, I see two approaches:
Either use a list comprehension, containing literally each char for each of the strings:
>>> lst = ['oz_', 'A', 'ab']
>>> [char for string in lst for char in string]
['o', 'z', '_', 'A', 'a', 'b']
Or join the strings and turn the result into a list:
>>> list(''.join(lst))
['o', 'z', '_', 'A', 'a', 'b']
If A is meant to be a variable and you want to preserve it, things get more tricky. If A is a string, then that's just not possible, as A will get evaluated and is then indistinguishable from the other strings. If it is something else, then you will have to differentiate between the two types:
>>> joined = []
>>> for x in lst:
... joined += x if isinstance(x, str) else [x] # +x extends, +[x] appends
If the complete elements of the list were strings, You could use itertools.chain.from_iterable() , it takes an iterable (like list/tuple, etc) and then for each iterable element inside it, it creates a new list consisting of the elements of those inner iterables (which in this case are strings). Example -
In [5]: lst = ['oz_', 'A', 'ab']
In [6]: list(chain.from_iterable(lst))
Out[6]: ['o', 'z', '_', 'A', 'a', 'b']
As given in the updated question -
A is a list, so I don't want anything to change it.
You can do this (similar to what #SuperBiasedMan is suggesting) (For Python 3.x) -
In [14]: lst = ['oz_', 'A', 'ab',[1,2,3]]
In [15]: ret = []
In [18]: for i in lst:
....: if isinstance(i, str):
....: ret.extend(i)
....: else:
....: ret.append(i)
....:
In [19]: ret
Out[19]: ['o', 'z', '_', 'A', 'a', 'b', [1, 2, 3]]
You can use basestring in Python 2.x to account for both unicode as well as normal strings.
Please also note, the above method does not check whether a particular object in the list came from variable or not, it just breaks strings up into characters and for all other types it keeps it as it is.
>>> [a for a in ''.join(['oz_', 'A', 'ab'])]
['o', 'z', '_', 'A', 'a', 'b']
You can use chain.from_iterable either way, you just need to wrap your non strings in a list:
from itertools import chain
out = list(chain.from_iterable([sub] if not isinstance(sub, str) else sub for sub in l))
When i was studying Python course of Codecademy, they said 'Methods that use dot notation only work with strings',
so... Is .sort() method only working in String type?, or Can it sort with other types? (int, float, etc)
Why didn't you quickly try it yourself?
>>> l = ['c', 'b', 'a']
>>> l.sort()
>>> l
['a', 'b', 'c']
>>> l = [3, 2, 1]
>>> l.sort()
>>> l
[1, 2, 3]
>>>
Actually string or string type can't be sorted using sort(). For example if you choose to do like the following
name = "hello"
print name.sort()
then it'll throw an error.But still if you really like to sort string or string types then try using sorted() as shown below.
name = "hello"
print sorted(name)
output:
['e', 'h', 'l', 'l', 'o']
Note: Upper case letters take the precedence over the lower case letters while sorting.
Is there an easy way to sort the letters in a string alphabetically in Python?
So for:
a = 'ZENOVW'
I would like to return:
'ENOVWZ'
You can do:
>>> a = 'ZENOVW'
>>> ''.join(sorted(a))
'ENOVWZ'
>>> a = 'ZENOVW'
>>> b = sorted(a)
>>> print b
['E', 'N', 'O', 'V', 'W', 'Z']
sorted returns a list, so you can make it a string again using join:
>>> c = ''.join(b)
which joins the items of b together with an empty string '' in between each item.
>>> print c
'ENOVWZ'
Sorted() solution can give you some unexpected results with other strings.
List of other solutions:
Sort letters and make them distinct:
>>> s = "Bubble Bobble"
>>> ''.join(sorted(set(s.lower())))
' belou'
Sort letters and make them distinct while keeping caps:
>>> s = "Bubble Bobble"
>>> ''.join(sorted(set(s)))
' Bbelou'
Sort letters and keep duplicates:
>>> s = "Bubble Bobble"
>>> ''.join(sorted(s))
' BBbbbbeellou'
If you want to get rid of the space in the result, add strip() function in any of those mentioned cases:
>>> s = "Bubble Bobble"
>>> ''.join(sorted(set(s.lower()))).strip()
'belou'
Python functionsorted returns ASCII based result for string.
INCORRECT: In the example below, e and d is behind H and W due it's to ASCII value.
>>>a = "Hello World!"
>>>"".join(sorted(a))
' !!HWdellloor'
CORRECT: In order to write the sorted string without changing the case of letter. Use the code:
>>> a = "Hello World!"
>>> "".join(sorted(a,key=lambda x:x.lower()))
' !deHllloorW'
OR (Ref: https://docs.python.org/3/library/functions.html#sorted)
>>> a = "Hello World!"
>>> "".join(sorted(a,key=str.lower))
' !deHllloorW'
If you want to remove all punctuation and numbers.
Use the code:
>>> a = "Hello World!"
>>> "".join(filter(lambda x:x.isalpha(), sorted(a,key=lambda x:x.lower())))
'deHllloorW'
You can use reduce
>>> a = 'ZENOVW'
>>> reduce(lambda x,y: x+y, sorted(a))
'ENOVWZ'
the code can be used to sort string in alphabetical order without using any inbuilt function of python
k = input("Enter any string again ")
li = []
x = len(k)
for i in range (0,x):
li.append(k[i])
print("List is : ",li)
for i in range(0,x):
for j in range(0,x):
if li[i]<li[j]:
temp = li[i]
li[i]=li[j]
li[j]=temp
j=""
for i in range(0,x):
j = j+li[i]
print("After sorting String is : ",j)
Really liked the answer with the reduce() function. Here's another way to sort the string using accumulate().
from itertools import accumulate
s = 'mississippi'
print(tuple(accumulate(sorted(s)))[-1])
sorted(s) -> ['i', 'i', 'i', 'i', 'm', 'p', 'p', 's', 's', 's', 's']
tuple(accumulate(sorted(s)) -> ('i', 'ii', 'iii', 'iiii', 'iiiim', 'iiiimp', 'iiiimpp', 'iiiimpps', 'iiiimppss', 'iiiimppsss', 'iiiimppssss')
We are selecting the last index (-1) of the tuple
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to create a list with the characters of a string?
Example:
'abc'
becomes
['a', 'b', 'c']
Is it a combination of split and slicing?
>>> x = 'abc'
>>> list(x)
['a', 'b', 'c']
Not sure what you are trying to do, but you can access individual characters from a string itself:
>>> x = 'abc'
>>> x[1]
'b'
If you need to iterate over the string you do not even need to convert it to a list:
>>> n = 'abc'
>>> for i in n:
... print i
...
a
b
c
or
>>> n[1]
'b'
yourstring = 'abc'
[char for char in yourstring]
This question already has answers here:
if/else in a list comprehension
(12 answers)
Closed 3 years ago.
Here is the code I was trying to turn into a list comprehension:
table = ''
for index in xrange(256):
if index in ords_to_keep:
table += chr(index)
else:
table += replace_with
Is there a way to add the else statement to this comprehension?
table = ''.join(chr(index) for index in xrange(15) if index in ords_to_keep)
The syntax a if b else c is a ternary operator in Python that evaluates to a if the condition b is true - otherwise, it evaluates to c. It can be used in comprehension statements:
>>> [a if a else 2 for a in [0,1,0,3]]
[2, 1, 2, 3]
So for your example,
table = ''.join(chr(index) if index in ords_to_keep else replace_with
for index in xrange(15))
To use the else in list comprehensions in python programming you can try out the below snippet. This would resolve your problem, the snippet is tested on python 2.7 and python 3.5.
obj = ["Even" if i%2==0 else "Odd" for i in range(10)]
If you want an else you don't want to filter the list comprehension, you want it to iterate over every value. You can use true-value if cond else false-value as the statement instead, and remove the filter from the end:
table = ''.join(chr(index) if index in ords_to_keep else replace_with for index in xrange(15))
Yes, else can be used in Python inside a list comprehension with a Conditional Expression ("ternary operator"):
>>> [("A" if b=="e" else "c") for b in "comprehension"]
['c', 'c', 'c', 'c', 'c', 'A', 'c', 'A', 'c', 'c', 'c', 'c', 'c']
Here, the parentheses "()" are just to emphasize the conditional expression, they are not necessarily required (Operator precedence).
Additionaly, several expressions can be nested, resulting in more elses and harder to read code:
>>> ["A" if b=="e" else "d" if True else "x" for b in "comprehension"]
['d', 'd', 'd', 'd', 'd', 'A', 'd', 'A', 'd', 'd', 'd', 'd', 'd']
>>>
On a related note, a comprehension can also contain its own if condition(s) at the end:
>>> ["A" if b=="e" else "c" for b in "comprehension" if False]
[]
>>> ["A" if b=="e" else "c" for b in "comprehension" if "comprehension".index(b)%2]
['c', 'c', 'A', 'A', 'c', 'c']
Conditions? Yes, multiple ifs are possible, and actually multiple fors, too:
>>> [i for i in range(3) for _ in range(3)]
[0, 0, 0, 1, 1, 1, 2, 2, 2]
>>> [i for i in range(3) if i for _ in range(3) if _ if True if True]
[1, 1, 2, 2]
(The single underscore _ is a valid variable name (identifier) in Python, used here just to show it's not actually used. It has a special meaning in interactive mode)
Using this for an additional conditional expression is possible, but of no real use:
>>> [i for i in range(3)]
[0, 1, 2]
>>> [i for i in range(3) if i]
[1, 2]
>>> [i for i in range(3) if (True if i else False)]
[1, 2]
Comprehensions can also be nested to create "multi-dimensional" lists ("arrays"):
>>> [[i for j in range(i)] for i in range(3)]
[[], [1], [2, 2]]
Last but not least, a comprehension is not limited to creating a list, i.e. else and if can also be used the same way in a set comprehension:
>>> {i for i in "set comprehension"}
{'o', 'p', 'm', 'n', 'c', 'r', 'i', 't', 'h', 'e', 's', ' '}
and a dictionary comprehension:
>>> {k:v for k,v in [("key","value"), ("dict","comprehension")]}
{'key': 'value', 'dict': 'comprehension'}
The same syntax is also used for Generator Expressions:
>>> for g in ("a" if b else "c" for b in "generator"):
... print(g, end="")
...
aaaaaaaaa>>>
which can be used to create a tuple (there is no tuple comprehension).
Further reading:
The Python Tutorial on Data Structures
List Comprehensions
Sets
Dictionaries
Also, would I be right in concluding that a list comprehension is the most efficient way to do this?
Maybe. List comprehensions are not inherently computationally efficient. It is still running in linear time.
From my personal experience:
I have significantly reduced computation time when dealing with large data sets by replacing list comprehensions (specifically nested ones) with for-loop/list-appending type structures you have above. In this application I doubt you will notice a difference.
Great answers, but just wanted to mention a gotcha that "pass" keyword will not work in the if/else part of the list-comprehension (as posted in the examples mentioned above).
#works
list1 = [10, 20, 30, 40, 50]
newlist2 = [x if x > 30 else x**2 for x in list1 ]
print(newlist2, type(newlist2))
#but this WONT work
list1 = [10, 20, 30, 40, 50]
newlist2 = [x if x > 30 else pass for x in list1 ]
print(newlist2, type(newlist2))
This is tried and tested on python 3.4.
Error is as below:
newlist2 = [x if x > 30 else pass for x in list1 ]
SyntaxError: invalid syntax
So, try to avoid pass-es in list comprehensions