简体   繁体   English

从 Python 中的字符串列表中提取和舍入数字

[英]Extract and round numbers from list of strings in Python

I have a Python list that contains strings, integers, and floats我有一个包含字符串、整数和浮点数的 Python 列表

my_list = [['100', '200.1', 'z', '300.9', '400', '100.2']]

I have been trying to figure out how to:我一直在试图弄清楚如何:

  • remove strings删除字符串
  • round floats and converts them to integers round 浮点数并将它们转换为整数
  • remove duplicates删除重复项

The goal is to return a list that looks similar to the list below目标是返回一个类似于下面列表的列表

new_list = [100, 200, 301, 400]

Is this possible and how should I approach this?这可能吗?我应该如何处理?

The safest way to remove any alphanumerics and convert rest to rounded int is something like the below:删除任何字母数字并将 rest 转换为舍入整数的最安全方法如下所示:

import re

my_list = [['100', '200.1', 'z', '1000_100', '300.9', '400', '100.2']]
my_list_2 = list(set([round(float(x)) for x in my_list[0] if re.fullmatch("[\d\.]+",x) is not None]))
print(my_list_2)

[200, 400, 100, 301] [200、400、100、301]

A much improved answer thanks to Alexander and Stefan.感谢 Alexander 和 Stefan,一个大大改进的答案。

Please note that your question has a list containing a list of strings.请注意,您的问题有一个包含字符串列表的列表。

If you actually have a list of strings, omit the [0] .如果您实际上有一个字符串列表,请省略[0]

result = []
for item in my_list[0]:
  try:
    v = float(item)
  except ValueError:
    continue
  v = int(round(v))

  if v not in result:
    result.append(v)

Then然后

print(result)
[100, 200, 301, 400]

Easiest way is to create a helper function that lets you convert to an int without throwing:最简单的方法是创建一个帮助器 function ,它可以让您在不抛出的情况下转换为 int:

my_list = [['100', '200.1', 'z', '300.9', '400', '100.2']]

def make_int(s):
    """
    Convert s to an int, rounding if it is a floating point value. 
    Return None if the conversion cannot be done.
    """

    try:
        return int(round(float(s)))
    except:
        return None

newlist = list(set([i for i in [make_int(s) for s in my_list[0]] if i != None]))

This involves two nested list comprehensions:这涉及两个嵌套列表推导:

The inner one converts the list to rounded floats, returning None for strings: [make_int(s) for s in my_list[0]]内部将列表转换为四舍五入的浮点数,为字符串返回None[make_int(s) for s in my_list[0]]

The outer one strips the None 's: [i for i in <inner> if i != None]外层去掉None的: [i for i in <inner> if i != None]

This also removes the need to muck with regexes.这也消除了使用正则表达式的需要。

It's a one liner这是一个班轮

list(dict.fromkeys(x for x in (round_or_none(s) for s in l) if x))

(if, of course, you have defined in advance the round_or_none function, (当然,如果您事先定义了round_or_none function,

def round_or_none(s):
    try:
        return round(float(s))
    except ValueError:
        pass

that is:-)那是:-)

Demo:演示:

>>> def round_or_none(s):
...     try:
...         return round(float(s))
...     except ValueError:
...         pass
... 
>>> l = ['100', '200.1', 'z', '300.9', '400', '100.2']
>>> list(dict.fromkeys(x for x in (round_or_none(s) for s in l) if x))
[100, 200, 301, 400]
>>>

Without the extra function没有额外的 function

rounded = []
for s in l:
    try:
         rounded.append(round(float(s)))
    except ValueError:
         pass
rounded = list(dict.fromkeys(rounded))

This works for Python 3.6 and newer, otherwise use an OrderedDict这适用于 Python 3.6 和更新版本,否则使用 OrderedDict

from collections import OrderedDict
...
rounded = list(OrderedDict.fromkeys(rounded))

Another approach: use more-itertools .另一种方法:使用more-itertools

from more-itertools import map_except, unique_everseen
my_list = ['100', '200.1', 'z', '300.9', '400', '100.2']

intlist = list(unique_everseen(map_except(lambda s: round(float(s)), my_list, ValueError)))
##########################################################################################

print(intlist) #> [100, 200, 301, 400]

Here are the docs这是文档

Simplest way is with a "try/catch" and just build the new list from that.最简单的方法是使用“try/catch”并从中构建新列表。

my_list = ['100', '200.1', 'z', '300.9', '400', '100.2']
new_list = []
for item in my_list:
    try:
        new_list.append(int(float(item)))
    except ValueError:
        pass

new_list = list(set(new_list))
print(new_list)

Alternative is to use a list comprehension.另一种方法是使用列表推导。 Use round instead of int if you want the rounding and not the truncation.如果您想要舍入而不是截断,请使用round而不是int

The "pythonic" one-liner: “pythonic”单线:

a = ['100', '200.1', 'z', '300.9', '400', '100.2']
list(set([int(round(float(b))) for b in a if b.isdigit()]))
>>> [400, 100]

Simple Answer简单的答案

my_list = [['100', '200.1', 'z', '300.9', '400', '100.2']]
new_list=[]
for i in my_list:
    for j in i:
        try:
            num=round(float(j))
            if num not in new_list:
                new_list.append(num)
        except:
            pass
print(new_list)

mmm in order to solve this, i would use a couple of tricks and a list comprehensions.嗯,为了解决这个问题,我会使用一些技巧和列表理解。

#with a regex you can define a matching pattern in order to
#clean the list of strings of every alpabetic element

import re
old = ['100', '200.1', 'z', '300.9', '400', '100.2']

# for every element that not match with capitals A to Z, or a to z
# make it a round float into this list.
new = [round(float(x)) for x in old if not re.match(r'[A-Za-z]',x)]
#clean the duplicates and print
print(list(set(new)))

True.真的。 I missed the float conversion first - shouldn't answer questions from the phone:) fixed我首先错过了浮动转换 - 不应该回答电话中的问题:) 已修复

The format of the list isn't clearly defined.列表的格式没有明确定义。 For the sake of this solution, I will assume that the input is a two-dimensional list of strings (AKA a list of list of strings).为了这个解决方案,我假设输入是一个二维的字符串列表(也就是字符串列表)。 If your lists follow a different format (multiple levels deep, sublists mixed in with strings, etc.) it is possible that lists are not the data structure you need.如果您的列表遵循不同的格式(多层次深度、与字符串混合的子列表等),则列表可能不是您需要的数据结构。

import itertools as itt

def str_to_int(str_in):
    try:
        res = round(float(str_in))
    except ValueError:
        res = None
    return res

def trans_lst(lst_in):
    flat_lst = itt.chain.from_iterable(lst_in)
    parse_res = (str_to_int(item) for item in flat_lst)
    res_lst = list(set((item for item in parse_res if item is not None)))

    return res_lst

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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