简体   繁体   中英

More pythonic/better way to write this?

I am checking if the sliced part of words in dictionary are in list, so I can know if words that end with ";" or are last in dictionary value are nouns in base form.

I have this code here:

dict = {"devotion": "andumus; pühendumust", "devotional": "vagasse",
        "devour": "kugistama; alla neelama", "devoured": "neelatud"}
endings2 = ["es", "te", "de", "st", "el", "le", "lt", "ks", "ni", "na",  "ta",  "ga", "id"]
endings3 = ["sse", "tte"]

for k, v in sorted(dict.items()):
    for x in v.split():
        if ((x[-1:] == ';' or x == v.split()[-1])
             and (x[-3:-1] not in endings2 and x[-4:-1] not in endings3
                 and x[-2:] not in endings2 and x[-3:] not in endings3)):
            print(k, x)

It works but it is kind of hardcoded. I would prefer to somehow use only one list for the cases/endings.

You ask about pythonic. In my opinion is the most pythonic approach to to use the features that are provided by python.

str.endswith

str.endswith(suffix[, start[, end]])

Return True if the string ends with the specified suffix, otherwise return False. suffix can also be a tuple of suffixes to look for. With optional start, test beginning at that position. With optional end, stop comparing at that position.

Changed in version 2.5: Accept tuples as suffix.

So it accepts a tuple , why not use that:

endings = tuple(endings2 + endings3)

if not x.endswith(endings):
    print(k, x)

Instead of using any and a comprehension or a manual loop here .


But there is another pythonic guideline ( import this )

[...]

Simple is better than complex.

[...]

There should be one-- and preferably only one --obvious way to do it.

[...]

I'm speaking about

if (x[-1:] == ';' or x == v.split()[-1])
#                 ^^^^^^^^^^^^^^^^^^^^^

what exactly are you trying to do. This compares your x which is v.split()[i] to v.split()[-1] ? I think that condition justifies a comment at the least. Why is it important to check if it's the last substring in the whole string?

That's probably not what you wanted but to give an example how a "pythonic" approach could look like:

for k, v in sorted(dict.items()):
    for x in v.split(';'):           # split at ';'
        x = x.strip()                # remove leading and trailing whitespaces
        if not x.endswith(endings):  # make sure it doesn't end with a forbidden ending
            print(k, x)

or:

for k, v in sorted(dict.items()):
    for x in v.split():              # split at whitespaces
        x = x.rstrip(';')            # remove TRAILING ";"
        if not x.endswith(endings):
            print(k, x)

Instead of

if x[-1] == ";" ...

you could use

if x.endswith(';') ...

To see if a word has one of the endings in your list you could strip the semi-colon and loop over the endings:

word = x.strip(';')
for ending in endings:
  if word.endswith(ending):
     ...

That way you don't have to treat endings of two and three letters differently.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM