在 Python 中的元组值列表中查找某个范围内的值
我正在尝试获取标准 BMI 范围内的 BMI 值的身体质量指数 (BMI) 分类 - 例如,如果某人的 BMI 为 26.2,则他们将处于“超重”范围内。
我制作了一个值元组列表(见下文),尽管我当然对任何其他数据结构持开放态度。使用 SQL 的 BETWEEN 可以很容易地做到这一点,但我想用纯 Python 来实现,主要是因为这意味着更少的数据库连接,而且也是在“纯”Python 中做更多事情的练习。
bmi_ranges = []
bmi_ranges.append((u'Underweight', u'Severe Thinness', 0, 15.99))
bmi_ranges.append((u'Underweight', u'Moderate Thinness', 16.00, 16.99))
bmi_ranges.append((u'Underweight', u'Mild Thinness', 17.00, 18.49))
bmi_ranges.append((u'Normal Range', u'Normal Range', 18.50, 24.99))
bmi_ranges.append((u'Overweight', u'Overweight', 25.00, 29.99))
bmi_ranges.append((u'Obese', u'Obese Class I', 30.00, 34.99))
bmi_ranges.append((u'Obese', u'Obese Class II', 35.00, 39.99))
bmi_ranges.append((u'Obese', u'Obese Class III', 40.00, 1000.00))
如果元组列表中的范围完全,那么只需使用 listcomp 进行迭代就很容易了,但是如何找到某个值在任何其他值的范围内呢?
I'm trying to get the Body Mass Index (BMI) classification for a BMI value that falls within a standard BMI range - for instance, if someone's BMI were 26.2, they'd be in the "Overweight" range.
I made a list of tuples of the values (see below), although of course I'm open to any other data structure. This would be easy to do with SQL's BETWEEN but I'd like to do it in pure Python, mostly because it means one fewer DB connections but also as an exercise in doing more in "pure" Python.
bmi_ranges = []
bmi_ranges.append((u'Underweight', u'Severe Thinness', 0, 15.99))
bmi_ranges.append((u'Underweight', u'Moderate Thinness', 16.00, 16.99))
bmi_ranges.append((u'Underweight', u'Mild Thinness', 17.00, 18.49))
bmi_ranges.append((u'Normal Range', u'Normal Range', 18.50, 24.99))
bmi_ranges.append((u'Overweight', u'Overweight', 25.00, 29.99))
bmi_ranges.append((u'Obese', u'Obese Class I', 30.00, 34.99))
bmi_ranges.append((u'Obese', u'Obese Class II', 35.00, 39.99))
bmi_ranges.append((u'Obese', u'Obese Class III', 40.00, 1000.00))
If a range is exactly in the list of tuples it's easy enough to just iterate through with a listcomp, but how do I find that a value is within the range of any of the other values?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您可以添加
if
子句来过滤结果中包含的项目的列表推导式。注意:您可能需要调整范围规范以使用非包含上限(即 [a,b) + [b,c) + [c,d) 等),然后将条件更改为
a <= b < c
,这样就不会出现边缘情况的问题。You can add
if
clauses to list comprehensions that filter what items are included in the result.Note: you may want to adjust your range specifications to use a non-inclusive upper bound (i.e. [a,b) + [b,c) + [c,d) et cetera), and then change the conditional to
a <= b < c
, that way you don't have issues with edge cases.您可以通过列表理解来完成此操作:
但是,请求数据库为您执行此操作可能会更快,否则您将请求比您需要的更多的数据。我不明白使用 BETWEEN 如何需要再使用一个数据连接。如果你能扩展它将会很有用。您是在谈论缓存数据与始终请求实时数据的优缺点吗?
您可能还想为您的数据创建一个类,以便不必将字段引用为 x[2],而是可以使用更有意义的名称。您还可以查看命名元组。
You can do this with a list comprehension:
However it would probably be faster to request the database to do this for you as otherwise you are requesting more data than you need. I don't understand how using a BETWEEN requires using one more data connection. If you could expand on that it would be useful. Are you talking about the pros and cons of caching data versus always asking for live data?
You may also want to create a class for your data so that you don't have to refer to fields as x[2], but instead can use more meaningful names. You could also look at namedtuples.
如果您喜欢更轻量级的原始数据结构并从标准库导入:
更多信息:bisect
If you like a lighter original data structure and one import from standard library:
More information: bisect
我不确定我是否理解为什么不能仅通过迭代列表来做到这一点(我知道有更有效的数据结构,但这很短,迭代会更容易理解)。出了什么问题
I'm not sure if I understand why you can't do this just by iterating over the list (I know there are more efficient datastructures, but this is very short and iteration would be more understandable). What's wrong with
这就是我处理它的方式:
This is how I would deal with it:
内置过滤器功能就是为此目的而存在的:
希望这有帮助
The builtin filter function exists for this purpose:
Hope this helps