Используйте MissingSchemaAction. Проигнорируйте как параметр MissingSchemaAction в Слиянии
table1.Merge(TempTable, True, MissingSchemaAction.Ignore)
Спасибо всем, кто предлагал решения и справлялся с моими иногда ошибочными наборами данных. Используя решение @hughdbrown , я изменил его так, как я хотел:
Модификация заключалась в использовании скользящего окна над целью, чтобы гарантировать, что последовательность подмножества найдена. Думаю, мне следовало использовать более подходящее слово, чем «Установить», для описания моей проблемы.
def is_sublist_of_any_list(cand, lists):
# Compare candidate to a single list
def is_sublist_of_list(cand, target):
try:
i = 0
try:
start = target.index(cand[0])
except:
return False
while start < (len(target) + len(cand)) - start:
if cand == target[start:len(cand)]:
return True
else:
start = target.index(cand[0], start + 1)
except ValueError:
return False
# See if candidate matches any other list
return any(is_sublist_of_list(cand, target) for target in lists if len(cand) <= len(target))
# Compare candidates to all other lists
def super_lists(lists):
a = [cand for i, cand in enumerate(lists) if not is_sublist_of_any_list(cand, lists[:i] + lists[i+1:])]
return a
lists = [[2, 16, 17], [1, 2, 3, 4, 5, 6, 7], [1], [1, 2, 3, 4], [1, 2], [17, 18, 19, 22, 41, 48], [2, 3], [1, 2, 3], [50, 69], [1, 2, 3], [2, 3, 21], [1, 2, 3], [1, 2, 4, 8], [1, 2, 4, 5, 6]]
expect = [[2, 16, 17], [1, 2, 3, 4, 5, 6, 7], [17, 18, 19, 22, 41, 48], [50, 69], [2, 3, 21], [1, 2, 4, 8], [1, 2, 4, 5, 6]]
def test():
out = super_lists(list(lists))
print "In : ", lists
print "Out : ", out
assert (out == expect)
Результат:
In : [[2, 16, 17], [1, 2, 3, 4, 5, 6, 7], [1], [1, 2, 3, 4], [1, 2], [17, 18, 19, 22, 41, 48], [2, 3], [1, 2, 3], [50, 69], [1, 2, 3], [2, 3, 21], [1, 2, 3], [1, 2, 4, 8], [1, 2, 4, 5, 6]]
Out : [[2, 16, 17], [1, 2, 3, 4, 5, 6, 7], [17, 18, 19, 22, 41, 48], [50, 69], [2, 3, 21], [1, 2, 4, 8], [1, 2, 4, 5, 6]]
This could be simplified, but:
l = [[1, 2, 4, 8], [1, 2, 4, 5, 6], [1, 2, 3], [2, 3, 21], [1, 2, 3, 4], [1, 2, 3, 4, 5, 6, 7]]
l2 = l[:]
for m in l:
for n in l:
if set(m).issubset(set(n)) and m != n:
l2.remove(m)
break
print l2
[[1, 2, 4, 8], [2, 3, 21], [1, 2, 3, 4, 5, 6, 7]]
A list is a superlist if it is not a subset of any other list. It's a subset of another list if every element of the list can be found, in order, in another list.
Here's my code:
def is_sublist_of_any_list(cand, lists):
# Compare candidate to a single list
def is_sublist_of_list(cand, target):
try:
i = 0
for c in cand:
i = 1 + target.index(c, i)
return True
except ValueError:
return False
# See if candidate matches any other list
return any(is_sublist_of_list(cand, target) for target in lists if len(cand) <= len(target))
# Compare candidates to all other lists
def super_lists(lists):
return [cand for i, cand in enumerate(lists) if not is_sublist_of_any_list(cand, lists[:i] + lists[i+1:])]
if __name__ == '__main__':
lists = [[1, 2, 4, 8], [1, 2, 4, 5, 6], [1, 2, 3], [2, 3, 21], [1, 2, 3, 4], [1, 2, 3, 4, 5, 6, 7]]
superlists = super_lists(lists)
print superlists
Here are the results:
[[1, 2, 4, 8], [2, 3, 21], [1, 2, 3, 4, 5, 6, 7]]
Edit: Results for your later data set.
>>> lists = [[2, 16, 17], [1, 2, 3, 4, 5, 6, 7], [1], [1, 2, 3, 4], [1, 2], [17,
18, 19, 22, 41, 48], [2, 3], [1, 2, 3], [50, 69], [1, 2, 3], [2, 3, 21], [1, 2,
3], [1, 2, 4, 8], [1, 2, 4, 5, 6]]
>>> superlists = super_lists(lists)
>>> expected = [[2, 16, 17], [1, 2, 3, 4, 5, 6, 7], [17, 18, 19, 22, 41, 48], [5
0, 69], [2, 3, 21], [1, 2, 4, 8]]
>>> assert(superlists == expected)
>>> print superlists
[[2, 16, 17], [1, 2, 3, 4, 5, 6, 7], [17, 18, 19, 22, 41, 48], [50, 69], [2, 3,
21], [1, 2, 4, 8]]
This code should be rather memory efficient. Beyond storing your initial list of lists, this code uses negligible extra memory (no temporary sets or copies of lists are created).
def is_subset(needle,haystack):
""" Check if needle is ordered subset of haystack in O(n) """
if len(haystack) < len(needle): return False
index = 0
for element in needle:
try:
index = haystack.index(element, index) + 1
except ValueError:
return False
else:
return True
def filter_subsets(lists):
""" Given list of lists, return new list of lists without subsets """
for needle in lists:
if not any(is_subset(needle, haystack) for haystack in lists
if needle is not haystack):
yield needle
my_lists = [[1, 2, 4, 8], [1, 2, 4, 5, 6], [1, 2, 3],
[2, 3, 21], [1, 2, 3, 4], [1, 2, 3, 4, 5, 6, 7]]
print list(filter_subsets(my_lists))
>>> [[1, 2, 4, 8], [2, 3, 21], [1, 2, 3, 4, 5, 6, 7]]
And, just for fun, a one-liner:
def filter_list(L):
return [x for x in L if not any(set(x)<=set(y) for y in L if x is not y)]
This seems to work:
original=[[1, 2, 4, 8], [1, 2, 4, 5, 6], [1, 2, 3], [2, 3, 21], [1, 2, 3, 4], [1, 2, 3, 4, 5, 6, 7]]
target=[[1, 2, 4, 8], [2, 3, 21], [1, 2, 3, 4, 5, 6, 7]]
class SetAndList:
def __init__(self,aList):
self.list=aList
self.set=set(aList)
self.isUnique=True
def compare(self,aList):
s=set(aList)
if self.set.issubset(s):
#print self.list,'superceded by',aList
self.isUnique=False
def listReduce(lists):
temp=[]
for l in lists:
for t in temp:
t.compare(l)
temp.append( SetAndList(l) )
return [t.list for t in temp if t.isUnique]
print listReduce(original)
print target
This prints the calculated list and the target for visual comparison.
Uncomment the print line in the compare method to see how various lists get superceded.
Tested with python 2.6.2
Я реализовал другой issubseq
, потому что ваш не говорит, что [1, 2, 4, 5, 6]
является подпоследовательностью [1, 2, 3, 4, 5, 6, 7]
, например (помимо того, что он очень медленный). Решение, которое я придумал, выглядит следующим образом:
def is_subseq(a, b):
if len(a) > len(b): return False
start = 0
for el in a:
while start < len(b):
if el == b[start]:
break
start = start + 1
else:
return False
return True
def filter_partial_matches(sets):
return [s for s in sets if all([not(is_subseq(s, ss)) for ss in sets if s != ss])]
Простой тестовый пример с учетом ваших входных и выходных данных:
>>> test = [[1, 2, 4, 8], [1, 2, 4, 5, 6], [1, 2, 3], [2, 3, 21], [1, 2, 3, 4], [1, 2, 3, 4, 5, 6, 7]]
>>> another_test = [[1, 2, 3, 4], [2, 4, 3], [3, 4, 5]]
>>> filter_partial_matches(test)
[[1, 2, 4, 8], [2, 3, 21], [1, 2, 3, 4, 5, 6, 7]]
>>> filter_partial_matches(another_test)
[[1, 2, 3, 4], [2, 4, 3], [3, 4, 5]]
Надеюсь, это поможет!
list0=[[1, 2, 4, 8], [1, 2, 4, 5, 6], [1, 2, 3], [2, 3, 21], [1, 2, 3, 4], [1, 2, 3, 4, 5, 6, 7]]
for list1 in list0[:]:
for list2 in list0:
if list2!=list1:
len1=len(list1)
c=0
for n in list2:
if n==list1[c]:
c+=1
if c==len1:
list0.remove(list1)
break
This filters list0 in place using a copy of it. This is good if the result is expected to be about the same size as the original, there is only a few "subset" to remove.
If the result is expected to be small and the original is large, you might prefer this one who is more memory freindly as it doesn't copy the original list.
list0=[[1, 2, 4, 8], [1, 2, 4, 5, 6], [1, 2, 3], [2, 3, 21], [1, 2, 3, 4], [1, 2, 3, 4, 5, 6, 7]]
result=[]
for list1 in list0:
subset=False
for list2 in list0:
if list2!=list1:
len1=len(list1)
c=0
for n in list2:
if n==list1[c]:
c+=1
if c==len1:
subset=True
break
if subset:
break
if not subset:
result.append(list1)
Изменить: Мне действительно нужно улучшить понимание прочитанного. Вот ответ на то, что на самом деле спросили. Он использует тот факт, что « A выше B
» подразумевает « len (A)> len (B) или A == B
».
def advance_to(it, value):
"""Advances an iterator until it matches the given value. Returns False
if not found."""
for item in it:
if item == value:
return True
return False
def has_supersequence(seq, super_sequences):
"""Checks if the given sequence has a supersequence in the list of
supersequences."""
candidates = map(iter, super_sequences)
for next_item in seq:
candidates = [seq for seq in candidates if advance_to(seq, next_item)]
return len(candidates) > 0
def find_supersequences(sequences):
"""Finds the supersequences in the given list of sequences.
Sequence A is a supersequence of sequence B if B can be created by removing
items from A."""
super_seqs = []
for candidate in sorted(sequences, key=len, reverse=True):
if not has_supersequence(candidate, super_seqs):
super_seqs.append(candidate)
return super_seqs
print(find_supersequences([[1, 2, 4, 8], [1, 2, 4, 5, 6], [1, 2, 3],
[2, 3, 21], [1, 2, 3, 4], [1, 2, 3, 4, 5, 6, 7]]))
#Output: [[1, 2, 3, 4, 5, 6, 7], [1, 2, 4, 8], [2, 3, 21]]
Если вам также необходимо сохранить исходный порядок последовательностей, то функция find_supersequences ()
должна отслеживать позиции последовательностей и впоследствии сортировать вывод.
Уточненный ответ после нового тестового примера:
original= [[2, 16, 17], [1, 2, 3, 4, 5, 6, 7], [1], [1, 2, 3, 4], [1, 2], [17, 18, 19, 22, 41, 48], [2, 3], [1, 2, 3], [50, 69], [1, 2, 3], [2, 3, 21], [1, 2, 3], [1, 2, 4, 8], [1, 2, 4, 5, 6]]
class SetAndList:
def __init__(self,aList):
self.list=aList
self.set=set(aList)
self.isUnique=True
def compare(self,other):
if self.set.issubset(other.set):
#print self.list,'superceded by',other.list
self.isUnique=False
def listReduce(lists):
temp=[]
for l in lists:
s=SetAndList(l)
for t in temp:
t.compare(s)
s.compare(t)
temp.append( s )
temp=[t for t in temp if t.isUnique]
return [t.list for t in temp if t.isUnique]
print listReduce(original)
Вы не дали требуемый результат, но я предполагаю, что это правильно, так как [1,2,3]
не отображается в выводе.
Итак, на самом деле вам нужно было знать, является ли список, так сказать, подстрокой другого, со всеми соответствующими элементами подряд. Вот код, который преобразует кандидата и целевой список в строки, разделенные запятыми, и выполняет сравнение подстрок, чтобы увидеть, появляется ли кандидат в целевом списке
def is_sublist_of_any_list(cand, lists):
def comma_list(l):
return "," + ",".join(str(x) for x in l) + ","
cand = comma_list(cand)
return any(cand in comma_list(target) for target in lists if len(cand) <= len(target))
def super_lists(lists):
return [cand for i, cand in enumerate(lists) if not is_sublist_of_any_list(cand, lists[:i] + lists[i+1:])]
. Функция comma_list () помещает начальные и конечные запятые в список, чтобы гарантировать, что целые числа полностью разделены. В противном случае [1] будет, например, подмножеством [100].