Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python conditional list joins

I have a list that looks like this:

[
  'A',
  'must',
  'see',
  'is',
  'the',
  'Willaurie',
  ',',
  'which',
  'sank',
  'after', 
  'genoegfuuu',
  'damaged',
  'in',
  'a',
  'storm',
  'in',
  '1989',
  '.'
]

As you can see, there is punctuation. I want to call .join using a blank space except for the cases where the string is punctuation, then I don't want a separator.

What's the best way to do this?
I've been trying for a while and my solutions are getting way too complicated for what seems like a simple task.

Thanks

like image 993
gEr Avatar asked Aug 01 '11 23:08

gEr


People also ask

Can I use join on a list python?

Python Join List. We can use the python string join() function for joining a list of the strings. However, this function takes iterable as an argument and the list is iterable, so we are able to use it with the list.

What is .join in python?

Python String join() Method The join() method takes all items in an iterable and joins them into one string. A string must be specified as the separator.

Is join faster than concatenation python?

String join is significantly faster then concatenation.


2 Answers

The string module has a list containing all punctuation characters.

import string
string = ''.join([('' if c in string.punctuation else ' ')+c for c in wordlist]).strip()
like image 159
BrainStorm Avatar answered Sep 23 '22 11:09

BrainStorm


You have your answer already, but just would like to add, that not all punctuation should be stuck to a left-hand side. If you want to deal with more general sentences, you could have for example parentheses or apostrophes, and you don't want to end up with something like:

It' s a great movie( best I' ve seen)

I'd say it's pointless to create some nasty one-liner, just to do this in most pythonic way. If you don't need super fast solution, you could consider solving it step-by-step, for example:

import re
s = ['It', "'", 's', 'a', 'great', 'movie', 
     '(', 'best', 'I', "'", 've', 'seen', ')']

s = " ".join(s) # join normally
s = re.sub(" ([,.;\)])", lambda m: m.group(1), s) # stick to left
s = re.sub("([\(]) ", lambda m: m.group(1), s)    # stick to right
s = re.sub(" ([']) ", lambda m: m.group(1), s)    # join both sides

print s # It's a great movie (best I've seen)

It's pretty flexible and you can specify which punctuation is handled by each rule... It has 4 lines though, so you might dislike it. No matter which method you choose, there'll be probably some sentences that won't work correctly and need special case, so one-liner may be just a bad choice anyway.

EDIT: Actually, you can contract the above solution to one line, but as said before, I'm pretty sure there are more cases to consider:

print re.sub("( [,.;\)]|[\(] | ['] )", lambda m: m.group(1).strip(), " ".join(s))
like image 38
tomasz Avatar answered Sep 24 '22 11:09

tomasz