Separating strings with lists - python

I was trying to find a way to separate strings in a project of my called 'Chemistry Calculator'. This project takes strings from an input() and compare it in a list:
substance1 = input('Substance 1: ')
substance2 = input('Substance 2: ')
elements = ['f','o','cl','br','i','s','c']
def affinity_table(element1:str,element2:str,table:list) -> str:
s = element1.lower()
r = element2.lower()
if s in table and r in table:
if table.index(s) < table.index(r):
print(s," will chage with ", r)
else:
print(s," won't change with ", r)
else:
print("Those substances are't in the list")
This code above works well.
So I wanted to have it working with hole substances and not just the element. To do this I need to separate the substance in to parts:
the cations parts
the anions parts.
Then I need to compare them with the list. I noticed that the contains() function showed exactly what I wanted, but only with one comparison.
My question came from:
Is there a way of using the contains() function with more than one string and then separate the string in to where the similarity is found.
Something similar to this:
a = 'NaCO3' #First input.
b = 'KCO3' #Second input.
list = ['Na','K'] #The list.
# Way of separating the values with the list.
# ^ my objective.
a1 = 'Na' #Separation with a.
a2 = 'CO3' #The rest of a.
b1 = 'K' #The rest of b.
b2 = 'CO3' #The rest of b.
# ^ expected outputs from the separation.
if table.index(a1) < table.index(a2):
print(a1,' will change with ', b1, 'and become', a1 + b2)
else:
print(a1," won't change with ", b1, 'and will stay normal')
# ^ the list index comparison from the 1st code.
#After the solution, here are the results:

Disclaimer
Just to be clear: for the constrained scope of what you are doing this solution might be applicable. If you want to parse any chemical compound (and those can look quite complicated) you need a full fledged parser, not the toy regex solution I came up with.
Here's an idea:
Dynamically build a regex with elements from your list as alternating matching groups. (re.split keeps groups when splitting.)
>>> import re
>>> lst = ['Na', 'K']
>>> regex = '|'.join('({})'.format(a) for a in lst)
>>> regex
>>> '(Na)|(K)'
Apply the regex...
>>> re.split(regex, 'NaCO3')
>>> ['', 'Na', None, 'CO3']
>>> re.split(regex, 'KCO3')
>>> ['', None, 'K', 'CO3']
... and filter out falsy values (None, '')
>>> list(filter(None, re.split(regex, 'NaCO3')))
>>> ['Na', 'CO3']
>>> list(filter(None, re.split(regex, 'KCO3')))
>>> ['K', 'CO3']
You can assign to those values with extended iterable unpacking:
>>> b1, b2, *unexpected_rest = filter(None, re.split(regex, 'KCO3'))
>>> b1
>>> 'K'
>>> b2
>>> 'CO3'
If you want to bias the split in favor of longer matches, sort lst in descending order first.
Not good:
>>> lst = ['N', 'Na', 'CO3']
>>> regex = '|'.join('({})'.format(a) for a in lst)
>>> list(filter(None, re.split(regex, 'NaCO3')))
>>> ['N', 'a', 'CO3']
Better:
>>> lst = ['N', 'Na', 'CO3']
>>> lst = sorted(lst, key=len, reverse=True)
>>> regex = '|'.join('({})'.format(a) for a in lst)
>>> list(filter(None, re.split(regex, 'NaCO3')))
>>> ['Na', 'CO3']
Let me know if that works for you.

Related

Python: append/ extend method

Can someone explain me why after the for loop the list res is ['m']?
string = 'spam'
for x in string:
res =[]
res.extend(x)
print(res)
I expected the output to be res = ['s', 'p', 'a', 'm']
You are replacing the list object each step of your loop. The statement res = [] creates a new, empty list object, then adds a single letter to that list.
Without the loop, this is what you are doing:
>>> x = 's'
>>> res = []
>>> res.extend(x)
>>> res
['s']
>>> x = 'p'
>>> res = []
>>> res.extend(x)
['p']
>>> x = 'a'
>>> res = []
>>> res.extend(x)
>>> res
['a']
>>> res = []
>>> x = 'm'
>>> res.extend(x)
>>> res
['m']
Create the list outside of the loop, once:
string = 'spam'
res = []
for x in string:
res.extend(x)
print(res)
Now you don't keep replacing the list object with a new one each iteration of the for loop.
Again, removing the loop and doing the steps manually, now we have:
>>> res = []
>>> x = 's'
>>> res.extend(x)
>>> res
['s']
>>> x = 'p'
>>> res.extend(x)
>>> res
['s', 'p']
>>> x = 'a'
>>> res.extend(x)
>>> res
['s', 'p', 'a']
>>> x = 'm'
>>> res.extend(x)
>>> res
['s', 'p', 'a', 'm']
Not that you should be using res.extend() here; it only works because individual letters in string assigned to x are each also strings and even single-letter strings are still sequences. What you are really doing with res.extend(x) is the equivalent of for element in x: res.append(element), but x will always have just one element.
So this would work too:
string = 'spam'
res = []
for x in string:
res.append(x)
print(res)
or just extend res with the whole string value:
string = 'spam'
res = []
res.extend(string)
print(res)
or, if you just wanted a list of all the characters of a string, just use the list() function:
string = 'spam'
res = list(string)
print(res)
list() does exactly what you wanted to do with your loop: create an empty list, loop over the input, and add each element to the new list, which is then returned:
>>> string = 'spam'
>>> list(string)
['s', 'p', 'a', 'm']
You are resetting res every time inside the loop. You need to use this-
string = ‘spam’
res =[]
for x in string:
res.extend(x)
print(res)
You'll never get that output because for every iteration of the loop, you are setting res = [] and therefore only the last iteration will work by extending the blank list with 'm'.
The fixed code looks like this:
string = 'spam'
res = []
for x in string:
res.extend(x)
print(res)
Another note is that you probably should use .append in this case. .extend is for appending an entire iterable but since you are only adding one element at a time it isn't necessary. Check here for a good explanation.
Also a last note here is that you'll want to be careful with editing python code outside of plain text or code editors. You're using some leading and trailing apostrophes ‘’ instead of regular '' which will cause you trouble at some point.
You are always re-initializing the res list in the for-loop, that is why in the last iteration of the loop the list is initialized to [] an empty list and the last letter is added to it.
string = 'spam'
res =[]
for x in string:
res.extend(x)
print(res)
or to make it simple, use the list builtin which takes an iterable like a string and converts it into an list object:
>>> list('spam')
['s', 'p', 'a', 'm']
I think this is simplest way:
string = 'spam'
res = list(string)

How to select a number without replacement in python

So I'm trying to make a mix and match between numbers here is my code
import random
P1 = float(input("Person's name?"))
P2 = float(input("Person's name?"))
P3 = float(input("Person's name?"))
A1 = float(input("Activity?"))
A2 = float(input("Activity?"))
A3 = float(input("Activity?"))
s = (A1, A2, A3)
cool1 = random.sample([A1, A2, A3],1)
cool2 = random.sample([A1, A2, A3],1)
cool3 = random.sample([A1, A2, A3],1)
print ("%s job is %s." %(P1, cool1))
print ("%s job is %s." %(P2, cool2))
print ("%s job is %s." %(P3, cool3))
The problem is that it is randomizing but it keeps repeating numbers like here
**
1.0 job is [4.0].
2.0 job is [5.0].
3.0 job is [4.0].
**
What can I do to make it not repeat.
I'm using python 2.7.12
Also how can I use alphanumerical instead of float only.
Best way to achieve this will be to use random.shuffle (if you want to randomize the original sample list) or random.select (if you want to keep the original sample copy):
Example with random.shuffle:
>>> import random
>>> my_samples = ['A1', 'A2', 'A3']
>>> shuffle(my_samples)
>>> cool1, cool2, cool3 = my_samples
# Random Result: cool1 = 'A3', cool2='A1', cool3='A2'
Example with random.select:
>>> cool1, cool2, cool3 = random.sample(['A1', 'A2', 'A3'], 3)
If you want minimal changes in your solution. You may remove an entry from your samples based on random selection and get next choice from remaining samples like:
>>> import random
>>> cool1 = random.sample(my_samples,1)
>>> my_samples.remove(*cool1)
>>> my_samples
['A1', 'A3']
>>> cool2 = random.sample(my_samples,1)
>>> my_samples.remove(*cool2)
>>> cool3 = random.sample(my_samples,1)
>>> my_samples.remove(*cool3)
>>> my_samples
[]
>>> cool1, cool2, cool3
(['A2'], ['A3'], ['A1'])
write a class to pick a unique element from list
1. permutations finds all unique elements
2. rest can define new data and length of result
from itertools import permutations
class PickOne( object ):
def __init__(self,lst,l):
self.lst = lst
self.visit = set()
self.l = l
self.lenght = self.number(l)
def pick(self):
if len(self.visit) == self.lenght :
print 'run out numbers'
return
res = tuple(random.sample(self.lst,self.l))
while res in self.visit:
res = tuple(random.sample(self.lst,self.l))
self.visit.add( res )
return res
def reset(self,l,lst = None):
if not lst:
lst = self.lst
self.__init__(lst,l)
def number(self,l):
return len( list(permutations(self.lst,l)) )
Example:
a = PickOne([1,2,3,4],1)
>>> a.pick()
(2,)
>>> a.pick()
(1,)
>>> a.pick()
(4,)
>>> a.pick()
(3,)
>>> a.pick()
run out numbers
>>> a.reset(2)
>>> a.pick()
(3, 1)
>>> a.pick()
(3, 4)
>>> a.pick()
(2, 1)
Since you are selecting from a list, then you should delete the entry from the list after each check.
Create your original list, which will be used as needed.
Create a second list from the first to use as you select.
As you choose each element from the list, remove it
Put the chosen element into a list of chosen element.
Python remove method
Parameters
obj -- This is the object to be removed from the list.
Return Value
This method does not return any value but removes the
given object from the list.
Example
The following example shows the usage of remove() method.
#!/usr/bin/python
aList = [123, 'xyz', 'zara', 'abc', 'xyz'];
aList.remove('xyz');
print "List : ", aList
aList.remove('abc');
print "List : ", aList
When we run above program, it produces following result −
List : [123, 'zara', 'abc', 'xyz']
List : [123, 'zara', 'xyz']
You could do this:
cool1, cool2, cool3 = random.sample([A1, A2, A3], 3)
Also how can I use alphanumerical instead of float only.
Have you tried not converting your inputs to float...?

Splitting a string based on a certain set of words

I have a list of strings like such,
['happy_feet', 'happy_hats_for_cats', 'sad_fox_or_mad_banana','sad_pandas_and_happy_cats_for_people']
Given a keyword list like ['for', 'or', 'and'] I want to be able to parse the list into another list where if the keyword list occurs in the string, split that string into multiple parts.
For example, the above set would be split into
['happy_feet', 'happy_hats', 'cats', 'sad_fox', 'mad_banana', 'sad_pandas', 'happy_cats', 'people']
Currently I've split each inner string by underscore and have a for loop looking for an index of a key word, then recombining the strings by underscore. Is there a quicker way to do this?
>>> [re.split(r"_(?:f?or|and)_", s) for s in l]
[['happy_feet'],
['happy_hats', 'cats'],
['sad_fox', 'mad_banana'],
['sad_pandas', 'happy_cats', 'people']]
To combine them into a single list, you can use
result = []
for s in l:
result.extend(re.split(r"_(?:f?or|and)_", s))
>>> pat = re.compile("_(?:%s)_"%"|".join(sorted(split_list,key=len)))
>>> list(itertools.chain(pat.split(line) for line in data))
will give you the desired output for the example dataset provided
actually with the _ delimiters you dont really need to sort it by length so you could just do
>>> pat = re.compile("_(?:%s)_"%"|".join(split_list))
>>> list(itertools.chain(pat.split(line) for line in data))
You could use a regular expression:
from itertools import chain
import re
pattern = re.compile(r'_(?:{})_'.format('|'.join([re.escape(w) for w in keywords])))
result = list(chain.from_iterable(pattern.split(w) for w in input_list))
The pattern is dynamically created from your list of keywords. The string 'happy_hats_for_cats' is split on '_for_':
>>> re.split(r'_for_', 'happy_hats_for_cats')
['happy_hats', 'cats']
but because we actually produced a set of alternatives (using the | metacharacter) you get to split on any of the keywords:
>>> re.split(r'_(?:for|or|and)_', 'sad_pandas_and_happy_cats_for_people')
['sad_pandas', 'happy_cats', 'people']
Each split result gives you a list of strings (just one if there was nothing to split on); using itertools.chain.from_iterable() lets us treat all those lists as one long iterable.
Demo:
>>> from itertools import chain
>>> import re
>>> keywords = ['for', 'or', 'and']
>>> input_list = ['happy_feet', 'happy_hats_for_cats', 'sad_fox_or_mad_banana','sad_pandas_and_happy_cats_for_people']
>>> pattern = re.compile(r'_(?:{})_'.format('|'.join([re.escape(w) for w in keywords])))
>>> list(chain.from_iterable(pattern.split(w) for w in input_list))
['happy_feet', 'happy_hats', 'cats', 'sad_fox', 'mad_banana', 'sad_pandas', 'happy_cats', 'people']
Another way of doing this, using only built-in method, is to replace all occurrence of what's in ['for', 'or', 'and'] in every string with a replacement string, say for example _1_ (it could be any string), then at then end of each iteration, to split over this replacement string:
l = ['happy_feet', 'happy_hats_for_cats', 'sad_fox_or_mad_banana','sad_pandas_and_happy_cats_for_people']
replacement_s = '_1_'
lookup = ['for', 'or', 'and']
lookup = [x.join('_'*2) for x in lookup] #Changing to: ['_for_', '_or_', '_and_']
results = []
for i,item in enumerate(l):
for s in lookup:
if s in item:
l[i] = l[i].replace(s,'_1_')
results.extend(l[i].split('_1_'))
OUTPUT:
['happy_feet', 'happy_hats', 'cats', 'sad_fox', 'mad_banana', 'sad_pandas', 'happy_cats', 'people']

How to generate a list of all possible alphabetical combinations based on an input of numbers

I have just come across an interesting interview style type of question which I couldn't get my head around.
Basically, given a number to alphabet mapping such that [1:A, 2:B, 3:C ...], print out all possible combinations.
For instance "123" will generate [ABC, LC, AW] since it can be separated into 12,3 and 1,23.
I'm thinking it has to be some type of recursive function where it checks with windows of size 1 and 2 and appending to a previous result if it's a valid letter mapping.
If anyone can formulate some pseudo/python code that'd be much appreciated.
So I managed to hack together an answer, it's not as pythonic as I'd like and there may be some redundancies, but it works with the 123 example to output ABC,AW, and LC.
I'll probably clean it up tomorrow (or if someone wants to clean it up), just posting it in case someone is also working on it and is wondering.
def num_to_alphabet(numbers, ans = ""):
if not numbers:
print ans
numbers = str(numbers)
window = numbers[:2]
alph = string.uppercase
ans = ans[:]
ans2 = ans[:]
window_val = ""
try:
if window[0]:
val = int(numbers[0])-1
if alph[val]:
ans += alph[val]
num_to_alphabet(numbers[1:], ans)
if window[1]:
val = int(window) -1
if alph[val]:
ans2 += alph[val]
if len(window) > 1:
num_to_alphabet(numbers[2:],ans2)
else:
num_to_alphabet(numbers[1:],ans2)
except IndexError:
pass
As simple as a tree
Let suppose you have give "1261"
Construct a tree with it a Root .
By defining the node(left , right ) , where left is always direct map and right is combo
version suppose for the if you take given Number as 1261
1261 ->
(1(261) ,12(61)) -> 1 is left-node(direct map -> a) 12 is right node(combo-map1,2->L)
(A(261) , L(61)) ->
(A(2(61),26(1))) ,L(6(1)) ->
(A(B(6(1)),Z(1)) ,L(F(1))) ->
(A(B(F(1)),Z(A)) ,L(F(A))) ->
(A(B(F(A)),Z(A)) ,L(F(A)))
so now you have got all the leaf node..
just print all paths from root to leaf node , this gives you all possible combinations .
like in this case
ABFA , AZA , LFA
So once you are done with the construction of tree just print all paths from root to node
which is your requirement .
charMap = {'1':'A', '2':'B' ... }
def getNodes(str):
results = []
if len(str) == 0: return results
c = str[0]
results.append(c)
results = results.join(c.join(getNodes(str[1:])))
if str[:2] in charMap.keys(): results = results.join(c.join(getNodes(str[2:])))
return results
def mapout(nodes):
cArray = []
for x in nodes:
cx = ''
for y in x:
cx = cx + charMap.get(y)
cArray.append(cx)
return cArray
res = getNodes('12345')
print(mapout(res))
Untested, but I believe this is along the lines of what you're looking for.
The following answer recursively tries all possibilities at the current position (there are more than two!) and goes on with the remainder of the string. That's it.
from string import ascii_uppercase
def alpha_combinations(s):
if len(s) == 0:
yield ""
return
for size in range(1, len(s) + 1):
v = int(s[:size])
if v > 26:
break
if v > 0:
c = ascii_uppercase[v - 1]
for ac in alpha_combinations(s[size:]):
yield c + ac
print(list(alpha_combinations(input())))
It expects a number as a string. It gives correct output for 101010 (['AAJ', 'AJJ', 'JAJ', 'JJJ']). (I think some of the other solutions don't handle zeroes correctly.)
So, I wanted to tackle this as well, since it’s actually a cool problem. So here goes my solution:
If we ignore the translations to strings for now, we are essentially looking for partitions of a set. So for the input 123 we have a set {1, 2, 3} and are looking for partitions. But of those partitions, only those are interesting which maintain the original order of the input. So we are actually not talking about a set in the end (where order doesn’t matter).
Anyway, I called this “ordered partition”—I don’t know if there actually exists a term for it. And we can generate those ordered partitions easily using recursion:
def orderedPartitions(s):
if len(s) == 0:
yield []
return
for i in range(1, len(s)+1):
for p in orderedPartitions(s[i:]):
yield [s[:i]] + p
For a string input '123', this gives us the following partions, which is exactly what we are looking for:
['1', '2', '3']
['1', '23']
['12', '3']
['123']
Now, to get back to the original problem which is asking for translations to strings, all we need to do is check each of those partitions, if they contain only valid numbers, i.e. 1 to 26. And if that is the case, translate those numbers and return the resulting string.
import string
def alphaCombinations(s):
for partition in orderedPartitions(str(s)):
# get the numbers
p = list(map(int, partition))
# skip invalid numbers
if list(filter(lambda x: x < 1 or x > 26, p)):
continue
# yield translated string
yield ''.join(map(lambda i: string.ascii_uppercase[i - 1], p))
And it works:
>>> list(alphaCombinations(123))
['ABC', 'AW', 'LC']
>>> list(alphaCombinations(1234))
['ABCD', 'AWD', 'LCD']
>>> list(alphaCombinations(4567))
['DEFG']
I still am not sure of the description, but this Python script first partitions the num into its 'breaks' then tries each break member as a whole as an index into its corresponding character; then converts each digit of the member into letters of a word. Both contributions are shown before showing the sum total of all conversions to letters/words for the num "123"
>>> import string
>>> mapping ={str(n):ch for n,ch in zip(range(1,27), string.ascii_uppercase)}
>>> num = '123'
>>> [[num[:i], num[i:]] for i in range(len(num)+1)]
[['', '123'], ['1', '23'], ['12', '3'], ['123', '']]
>>> breaks = set(part for part in sum(([num[:i], num[i:]] for i in range(len(num)+1)), []) if part)
>>> breaks
{'123', '12', '3', '1', '23'}
>>> as_a_whole = [mapping[p] for p in breaks if p in mapping]
>>> as_a_whole
['L', 'C', 'A', 'W']
>>> by_char = [''.join(mapping[n] for n in p) for p in breaks]
>>> by_char
['ABC', 'AB', 'C', 'A', 'BC']
>>> everything = sorted(set(as_a_whole + by_char))
>>> everything
['A', 'AB', 'ABC', 'BC', 'C', 'L', 'W']
>>>

How would you make a comma-separated string from a list of strings?

What would be your preferred way to concatenate strings from a sequence such that between every two consecutive pairs a comma is added. That is, how do you map, for instance, ['a', 'b', 'c'] to 'a,b,c'? (The cases ['s'] and [] should be mapped to 's' and '', respectively.)
I usually end up using something like ''.join(map(lambda x: x+',',l))[:-1], but also feeling somewhat unsatisfied.
my_list = ['a', 'b', 'c', 'd']
my_string = ','.join(my_list)
'a,b,c,d'
This won't work if the list contains integers
And if the list contains non-string types (such as integers, floats, bools, None) then do:
my_string = ','.join(map(str, my_list))
Why the map/lambda magic? Doesn't this work?
>>> foo = ['a', 'b', 'c']
>>> print(','.join(foo))
a,b,c
>>> print(','.join([]))
>>> print(','.join(['a']))
a
In case if there are numbers in the list, you could use list comprehension:
>>> ','.join([str(x) for x in foo])
or a generator expression:
>>> ','.join(str(x) for x in foo)
",".join(l) will not work for all cases. I'd suggest using the csv module with StringIO
import StringIO
import csv
l = ['list','of','["""crazy"quotes"and\'',123,'other things']
line = StringIO.StringIO()
writer = csv.writer(line)
writer.writerow(l)
csvcontent = line.getvalue()
# 'list,of,"[""""""crazy""quotes""and\'",123,other things\r\n'
Here is a alternative solution in Python 3.0 which allows non-string list items:
>>> alist = ['a', 1, (2, 'b')]
a standard way
>>> ", ".join(map(str, alist))
"a, 1, (2, 'b')"
the alternative solution
>>> import io
>>> s = io.StringIO()
>>> print(*alist, file=s, sep=', ', end='')
>>> s.getvalue()
"a, 1, (2, 'b')"
NOTE: The space after comma is intentional.
#Peter Hoffmann
Using generator expressions has the benefit of also producing an iterator but saves importing itertools. Furthermore, list comprehensions are generally preferred to map, thus, I'd expect generator expressions to be preferred to imap.
>>> l = [1, "foo", 4 ,"bar"]
>>> ",".join(str(bit) for bit in l)
'1,foo,4,bar'
Don't you just want:
",".join(l)
Obviously it gets more complicated if you need to quote/escape commas etc in the values. In that case I would suggest looking at the csv module in the standard library:
https://docs.python.org/library/csv.html
>>> my_list = ['A', '', '', 'D', 'E',]
>>> ",".join([str(i) for i in my_list if i])
'A,D,E'
my_list may contain any type of variables. This avoid the result 'A,,,D,E'.
l=['a', 1, 'b', 2]
print str(l)[1:-1]
Output: "'a', 1, 'b', 2"
#jmanning2k using a list comprehension has the downside of creating a new temporary list. The better solution would be using itertools.imap which returns an iterator
from itertools import imap
l = [1, "foo", 4 ,"bar"]
",".join(imap(str, l))
Here is an example with list
>>> myList = [['Apple'],['Orange']]
>>> myList = ','.join(map(str, [i[0] for i in myList]))
>>> print "Output:", myList
Output: Apple,Orange
More Accurate:-
>>> myList = [['Apple'],['Orange']]
>>> myList = ','.join(map(str, [type(i) == list and i[0] for i in myList]))
>>> print "Output:", myList
Output: Apple,Orange
Example 2:-
myList = ['Apple','Orange']
myList = ','.join(map(str, myList))
print "Output:", myList
Output: Apple,Orange
If you want to do the shortcut way :) :
','.join([str(word) for word in wordList])
But if you want to show off with logic :) :
wordList = ['USD', 'EUR', 'JPY', 'NZD', 'CHF', 'CAD']
stringText = ''
for word in wordList:
stringText += word + ','
stringText = stringText[:-2] # get rid of last comma
print(stringText)
Unless I'm missing something, ','.join(foo) should do what you're asking for.
>>> ','.join([''])
''
>>> ','.join(['s'])
's'
>>> ','.join(['a','b','c'])
'a,b,c'
(edit: and as jmanning2k points out,
','.join([str(x) for x in foo])
is safer and quite Pythonic, though the resulting string will be difficult to parse if the elements can contain commas -- at that point, you need the full power of the csv module, as Douglas points out in his answer.)
I would say the csv library is the only sensible option here, as it was built to cope with all csv use cases such as commas in a string, etc.
To output a list l to a .csv file:
import csv
with open('some.csv', 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(l) # this will output l as a single row.
It is also possible to use writer.writerows(iterable) to output multiple rows to csv.
This example is compatible with Python 3, as the other answer here used StringIO which is Python 2.
mmm also need for SQL is :
l = ["foo" , "baar" , 6]
where_clause = "..... IN ("+(','.join([ f"'{x}'" for x in l]))+")"
>> "..... IN ('foo','baar','6')"
enjoit
My two cents. I like simpler an one-line code in python:
>>> from itertools import imap, ifilter
>>> l = ['a', '', 'b', 1, None]
>>> ','.join(imap(str, ifilter(lambda x: x, l)))
a,b,1
>>> m = ['a', '', None]
>>> ','.join(imap(str, ifilter(lambda x: x, m)))
'a'
It's pythonic, works for strings, numbers, None and empty string. It's short and satisfies the requirements. If the list is not going to contain numbers, we can use this simpler variation:
>>> ','.join(ifilter(lambda x: x, l))
Also this solution doesn't create a new list, but uses an iterator, like #Peter Hoffmann pointed (thanks).

Categories

Resources