0

I am python/programming newbie. Using python 2.7

I have been trying to figure out how to 'subtract' the elements in 1 list from the elements in another list. However I put 'subtract' in quotes because I am not working with integers, and could not think of another way to explain.

First up, here is my code:

plural_string = "cell phones|sheep|oxen" # result of user input with raw_input()
plural_endings_string = "s,,en"                   # result of user input with raw_input() - always comma separated.  
plural_list = plural_string.split('|')
plural_endings_list = plural_endings_string.split(',')

# This is pseudo code since '-' does not work with non-integers in a string
# but it expresses what I am trying to achieve
new_list = [a - b for a, b in zip(plural_list, plural_endings_list)] 

So, what I actually want the new list to look like is this:

>>> new_list
>>> ['cell phone', 'sheep', 'ox']

I basically want to de-pluralize the words(elements) in the plural_list variable using the plural-endings(elements) in the plural_endings_list variable.

A key things to note is: The number of elements (and therefore word choices) in the lists will vary based on user input (me). So, in a different situation, the lists I am working with could look like this:

plural_list = ['children', 'brothers', 'fish', 'penguins']
plural_endings_list = ['ren', 's', '', 's']

I have tried to figure out how to do this using the strings - and not lists - using the '.replace' function, but I come up against a brick wall, given that I don't know what the user input will be in each run of the script. I could not find a '1 fits all' solution. Unsuccessfully tried regex too, and had the same problem of not knowing what the user input will be. It is beyond my newbie brain right now.

Hopefully, I have explained myself clearly! If not I am trying to do the opposite of this other question in SO - How do i add two lists' elements into one list? But, instead of concatenation, I need 'subtraction'

Cheers Darren

EDIT1: In response to @brad comment. I actually feed in the plural endings to the plural_endings_list via user input (this is part of a larger script). So if a list contains the element "children's", then I would choose "'s" as the ending for the plural_endings_list. It is always case specific.

EDIT2: In response to @Graeme Stuart comment. Graeme - the input will always vary in length. There could be 2 elements in each list, or there could be 10 elements in each list, or anything in between.

Community
  • 1
  • 1
Darren Haynes
  • 1,343
  • 4
  • 18
  • 31
  • how do you want to handle cases like children's? Make it child's? strip the 's as well? – Brad Oct 08 '13 at 20:32

3 Answers3

1
>>> p = 'children'
>>> e = 'ren'
>>> if p.endswith(e):
...   print p[:-len(e)]
... 
child
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
1

I think this does what you need. Its a bit clunky though. Will your input always be the same length?

def depluralise(plurals, plural_endings):
    new_list = []
    for plural, plural_ending in zip(plurals, plural_endings):
        if plural.endswith(plural_ending):
            if plural_ending == '':
                new_list.append(plural)
            else:
                new_list.append(plural[:-len(plural_ending)])
    return new_list 


plural_string = "cell phones|sheep|oxen"
plurals = plural_string.split('|')
plural_endings_string = "s,,en"
plural_endings = plural_endings_string.split(',')

print depluralise(plurals, plural_endings)

plurals = ['children', 'brothers', 'fish', 'penguins']
plural_endings = ['ren', 's', '', 's']

print depluralise(plurals, plural_endings)
Graeme Stuart
  • 5,837
  • 2
  • 26
  • 46
0

This may not be the answer you want, but to get the best de-pluralization, you'd want a dictionary of nouns and their plurals.

Search for the plural, and replace it with the singular.

I'd think you'd pull less hair out doing it this way than trying to handle all of the exceptions you'd run into:

  • women
  • geese
  • phenomena
  • data
  • dice
  • ...
John
  • 15,990
  • 10
  • 70
  • 110