我为我的目的创建了一个数据结构,这是一个简单的字典,其中包含值列表作为数据:
{'Procedure_name': ('compound', 'hardware', 'tempval', 'colorval', 'energyval'), .....}
想象一系列程序,其中混合2种化合物,记录温度变化,势能,颜色变化等,这就是字典中每个条目所代表的内容。
实现过滤器实现的最佳方法是什么?这是想要实现的一个例子。我的过滤器主要用于使用少量参数(如复合,硬件),无论是单个还是组合
dataset = {'Att1_Cl': ('carb', 'Spectrometer_v1', '33', '0.25', '445'),
'Att1_Na': ('carb', 'Spectrometer_v1', '34.2', '0.21', '401'),
'Att1_Si': ('alc', 'Photometer_V2', '32.1', '0.43', '521'),
'Att1_Cr': ('carb', 'Photometer_V3', '32.5', '0.49', '511')}
def filter_data(filter)
....
return filtered_data # the entry from the dictionary that satisfy the condition
作为输出示例:
print (filter_data (['carb']))
Att1_Cl
('carb', 'Spectrometer_v1', '33', '0.25', '445')
Att1_Na
('carb', 'Spectrometer_v1', '34.2', '0.21', '401')
Att1_Cr
('carb', 'Photometer_V3', '32.5', '0.49', '511')
print (filter_data (['Spectrometer_v1']))
Att1_Cl
('carb', 'Spectrometer_v1', '33', '0.25', '445')
Att1_Na
('carb', 'Spectrometer_v1', '34.2', '0.21', '401')
print (filter_data (['carb', 'Photometer_V3']))
Att1_Cr
('carb', 'Photometer_V3', '32.5', '0.49', '511')
我在考虑使用列表作为可能的参数,并比较数据集中的每个条目;但我找不到一种有效的方法来完成这项工作。这是我的第一个方法
def filter_data(filter):
for procedure in dataset:
single_dataset = dataset[procedure]
if filter in single_dataset:
print(procedure)
print(single_dataset)
如果我有一个条目,但是如果我在过滤器列表中有多个条目,则此方法有效;我必须在数据集上进行多次传递,如果我将向数据结构添加更多参数,这不是真正有效也不可扩展。 我想到的另一个选择是保存预先制作的过滤器,通过传递给函数的filter参数调用,但从维护代码的角度来看这是一场噩梦,因为过滤器中的每个更改都必须是硬编码。
答案 0 :(得分:0)
您可以将它们存储为嵌套字典,而不是将参数存储为list
。这将使过滤器实现更容易,并且还允许您基于参数而不仅仅是它们的值进行过滤。假设您要查找tempval == '30'
的所有过程。如果您致电filter_data (['30'])
,您可能会获得energyval
为'30'
的程序。
过滤嵌套dict
的一种方法是在if
块内使用带all
的生成器表达式。您可以轻松地将生成器转换为所需的返回类型,或在找到第一个匹配时终止过滤:
dataset = {
'Att1_Cl': {'compound': 'carb', 'hardware': 'Spectrometer_v1', 'tempval': '33', 'colorval': '0.25', 'energyval': '445'},
'Att1_Na': {'compound': 'carb', 'hardware': 'Spectrometer_v1', 'tempval': '34.2', 'colorval': '0.21', 'energyval': '401'},
'Att1_Si': {'compound': 'alc', 'hardware': 'Photometer_V2', 'tempval': '32.1', 'colorval': '0.43', 'energyval': '521'},
'Att1_Cr': {'compound': 'carb', 'hardware': 'Photometer_V3', 'tempval': '32.5', 'colorval': '0.49', 'energyval': '511'}
}
def filter_data(f):
return ((k, v) for k, v in dataset.items() if all(v[fk] == fv for fk, fv in f.items()))
print(list(filter_data({'compound': 'carb', 'hardware': 'Spectrometer_v1'})))
输出:
[('Att1_Cl', {'energyval': '445', 'tempval': '33', 'hardware': 'Spectrometer_v1', 'compound': 'carb', 'colorval': '0.25'}),
('Att1_Na', {'energyval': '401', 'tempval': '34.2', 'hardware': 'Spectrometer_v1', 'compound': 'carb', 'colorval': '0.21'})]
答案 1 :(得分:0)
我正在开发一个需要过滤功能的聊天机器人,我相信这些功能与您的需求类似。我维护着一个回复文章的数据库&#39;形式为<<response template>> #tag1 #tag2 ... #tagN
的形式。例如:&#34;你好,你好吗? #greeting
#wellbeing
&#34;。
这允许我在chatbot中实现逻辑,它尝试通过标记要求系统组成适当的响应,该系统支持&#34;和&#34;和&#34;或&#34;不合要求。这些子需求可以嵌套以形成树结构。
可以从字符串中解析这些标记要求。例如,字符串&#34;表达,可爱;表达,快乐&#34;任何包含 #emote
和#cute
或 #emote
和#happy
的回复文章都可以满足。
在您的情况下,响应文章类似于过程名称,以及过程属性的响应分类。您可以采用与我的方法类似的方法来指定诸如&#34;碳水化合物,光谱仪*; alk,光谱仪*&#34;匹配所有涉及光谱仪的程序,并涉及“碳水化合物”和“碳水化合物”。或者&#39; alk&#39; (或两者兼有)。
我的代码是用C#编写的,但希望你仍然觉得它很有用。 This page可能是开始寻找的最佳位置,您可以在this test class.
中查看其用法示例为了方便和冗余,我将复制下面的代码。
<强>实施强>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Mofichan.DataAccess
{
/// <summary>
/// Represents a tag requirement.
/// <para></para>
/// These will typically be used to filter the kind of responses
/// Mofichan will choose to respond with based on the tags
/// associated with each possible response she knows about.
/// </summary>
internal interface ITagRequirement
{
/// <summary>
/// Returns whether this <c>ITagRequirement</c> is satisfied by
/// the provided collection of tags.
/// </summary>
/// <param name="tags">The tag collection.</param>
/// <returns><c>true</c> if <c>this</c> is satisfied; otherwise, <c>false</c>.</returns>
bool SatisfiedBy(IEnumerable<string> tags);
}
/// <summary>
/// Provides static fields and methods.
/// </summary>
internal static class TagRequirement
{
internal static readonly char AndSeparator = ',';
internal static readonly char OrSeparator = ';';
private static readonly string TagMatch = @"[a-zA-Z0-9\-]+";
private static readonly string AndMatcher = string.Format(@"((?<and>{0}){1})*(?<and>{0})", TagMatch, AndSeparator);
private static readonly string OrMatcher = string.Format(@"^((?<or>{0}){1})*(?<or>{0})$", AndMatcher, OrSeparator);
/// <summary>
/// Parses a string and returns the represented <see cref="ITagRequirement"/>.
/// </summary>
/// <param name="representation">The tag requirement string representation.</param>
/// <returns>The represented tag requirement.</returns>
/// <exception cref="ArgumentException">Thrown if the representation is invalid.</exception>
public static ITagRequirement Parse(string representation)
{
var root = new AnyTagRequirement(from orGroup in GetMatchesFromRegex(representation, OrMatcher, "or")
let andGroup = from tag in GetMatchesFromRegex(orGroup, AndMatcher, "and")
select new LeafTagRequirement(tag)
let allTagRequirement = new AllTagRequirement(andGroup)
select allTagRequirement);
return root;
}
private static IEnumerable<string> GetMatchesFromRegex(string input, string pattern, string matchName)
{
var regex = Regex.Match(input, pattern);
if (!regex.Success)
{
var message = string.Format("Input '{0}' is invalid for pattern '{1}'", input, pattern);
throw new ArgumentException(message);
}
var captures = regex.Groups[matchName].Captures;
return from i in Enumerable.Range(0, captures.Count)
select captures[i].Value;
}
}
internal abstract class CompositeTagRequirement : ITagRequirement
{
protected CompositeTagRequirement(IEnumerable<ITagRequirement> children)
{
this.Children = children;
}
public IEnumerable<ITagRequirement> Children { get; }
public abstract bool SatisfiedBy(IEnumerable<string> tags);
}
internal sealed class AllTagRequirement : CompositeTagRequirement
{
public AllTagRequirement(IEnumerable<ITagRequirement> children) : base(children)
{
}
public override bool SatisfiedBy(IEnumerable<string> tags)
{
return this.Children.All(it => it.SatisfiedBy(tags));
}
public override string ToString()
{
return string.Join(TagRequirement.AndSeparator.ToString(), this.Children);
}
}
internal sealed class AnyTagRequirement : CompositeTagRequirement
{
public AnyTagRequirement(IEnumerable<ITagRequirement> children) : base(children)
{
}
public override bool SatisfiedBy(IEnumerable<string> tags)
{
return this.Children.Any(it => it.SatisfiedBy(tags));
}
public override string ToString()
{
return string.Join(TagRequirement.OrSeparator.ToString(), this.Children);
}
}
internal sealed class LeafTagRequirement : ITagRequirement
{
private readonly string requiredTag;
public LeafTagRequirement(string tag)
{
this.requiredTag = tag;
}
public bool SatisfiedBy(IEnumerable<string> tags)
{
return tags.Contains(this.requiredTag);
}
public override string ToString()
{
return this.requiredTag;
}
}
}
<强>测试强>
using System;
using System.Collections.Generic;
using Mofichan.DataAccess;
using Shouldly;
using Xunit;
namespace Mofichan.Tests.DataAccess
{
public class TagRequirementTests
{
public static IEnumerable<object> TagRequirementExamples
{
get
{
yield return new object[]
{
// Requirement
"foo",
// Satisfied by
new[]
{
new[] { "foo" },
},
// Unsatisfied by
new[]
{
new[] { "bar" },
new[] { "baz" },
},
};
yield return new object[]
{
// Requirement
"foo;bar",
// Satisfied by
new[]
{
new[] { "foo" },
new[] { "foo" },
new[] { "foo", "bar" },
},
// Unsatisfied by
new[]
{
new[] { "baz" },
},
};
yield return new object[]
{
// Requirement
"foo,bar;baz",
// Satisfied by
new[]
{
new[] { "foo", "bar", "baz" },
new[] { "foo", "bar" },
new[] { "foo", "baz" },
new[] { "baz" },
},
// Unsatisfied by
new[]
{
new[] { "bar" },
new[] { "foo" },
},
};
}
}
[Theory]
[MemberData(nameof(TagRequirementExamples))]
#pragma warning disable S2368 // Public methods should not have multidimensional array parameters
public void No_Exception_Should_Be_Thrown_When_Valid_Tag_Requirement_Representation_Is_Parsed(
#pragma warning restore S2368 // Public methods should not have multidimensional array parameters
string validRepresentation, string[][] _, string[][] __)
{
// EXPECT we can parse the valid tag requirement representation without exception.
TagRequirement.Parse(validRepresentation).ShouldNotBeNull();
}
[Theory]
[InlineData("")]
[InlineData("@illegal?characters")]
[InlineData("multiword tag without hyphen")]
public void Exception_Should_Be_Thrown_When_Invalid_Tag_Requirement_Representation_Is_Parsed(
string invalidRepresentation)
{
// EXPECT that an exception is thrown when we try to parse the invalid representation.
Assert.Throws<ArgumentException>(() => TagRequirement.Parse(invalidRepresentation));
}
[Theory]
[MemberData(nameof(TagRequirementExamples))]
#pragma warning disable S2368 // Public methods should not have multidimensional array parameters
public void Tag_Requirements_Should_Declare_Satisfaction_From_Provided_Tags_As_Expected(
#pragma warning restore S2368 // Public methods should not have multidimensional array parameters
string tagRequirementRepr,
string[][] expectedSatisfiedBy,
string[][] expectedUnsatisfiedBy)
{
// GIVEN a tag requirement based on the provided representation.
var tagRequirement = TagRequirement.Parse(tagRequirementRepr);
// EXPECT that the tag requirement is satisfied by provided groups of tags as appropriate.
expectedSatisfiedBy.ShouldAllBe(tagGroup => tagRequirement.SatisfiedBy(tagGroup));
// EXPECT that the tag requirement is unsatisfied by provided groups of tags as appropriate.
expectedUnsatisfiedBy.ShouldAllBe(tagGroup => !tagRequirement.SatisfiedBy(tagGroup));
}
}
}
答案 2 :(得分:0)
single_dataset = ['carb', 'Photometer_V3']
for procedure in dataset:
s = dataset[procedure]
if [ x for x in single_dataset if x in s] == single_dataset:
print procedure,s